Fix order of new objects in Prefab after apply

#357
This commit is contained in:
Wojtek Figat
2021-03-18 09:20:47 +01:00
parent 42366ee66a
commit a21f6d1b9f
2 changed files with 30 additions and 3 deletions

View File

@@ -834,7 +834,7 @@ bool Prefab::ApplyAllInternal(Actor* targetActor, bool linkTargetActorObjectToPr
sceneObjects->RemoveAtKeepOrder(i);
}
// Deserialize new prefab objects (add new objects)
// Deserialize new prefab objects
int32 newPrefabInstanceIdToDataIndexCounter = 0;
int32 newPrefabInstanceIdToDataIndexStart = sceneObjects->Count();
sceneObjects->Resize(sceneObjects->Count() + newPrefabInstanceIdToDataIndex.Count());
@@ -856,9 +856,27 @@ bool Prefab::ApplyAllInternal(Actor* targetActor, bool linkTargetActorObjectToPr
{
const int32 dataIndex = i->Value;
SceneObject* obj = sceneObjects->At(newPrefabInstanceIdToDataIndexStart + newPrefabInstanceIdToDataIndexCounter++);
if (obj)
if (!obj)
continue;
SceneObjectsFactory::Deserialize(obj, diffDataDocument[dataIndex], modifier.Value);
}
for (int32 j = 0; j < targetObjects->Count(); j++)
{
auto obj = targetObjects->At(j);
Guid prefabObjectId;
if (newPrefabInstanceIdToPrefabObjectId.TryGet(obj->GetSceneObjectId(), prefabObjectId))
{
SceneObjectsFactory::Deserialize(obj, diffDataDocument[dataIndex], modifier.Value);
newPrefabInstanceIdToDataIndexCounter = 0;
for (auto i = newPrefabInstanceIdToDataIndex.Begin(); i.IsNotEnd(); ++i)
{
SceneObject* e = sceneObjects->At(newPrefabInstanceIdToDataIndexStart + newPrefabInstanceIdToDataIndexCounter++);
if (e->GetID() == prefabObjectId)
{
// Synchronize order of new objects with the order in target instance
e->SetOrderInParent(obj->GetOrderInParent());
break;
}
}
}
}
Scripting::ObjectsLookupIdMapping.Set(nullptr);

View File

@@ -326,6 +326,15 @@ void SceneObjectsFactory::SynchronizePrefabInstances(Array<SceneObject*>& sceneO
for (int32 i = objectsToCheckCount; i < sceneObjects.Count(); i++)
{
SceneObject* obj = sceneObjects[i];
// Preserve order in parent (values from prefab are used)
auto prefab = Content::LoadAsync<Prefab>(obj->GetPrefabID());
const auto defaultInstance = prefab && prefab->IsLoaded() ? prefab->GetDefaultInstance(obj->GetPrefabObjectID()) : nullptr;
if (defaultInstance)
{
obj->SetOrderInParent(defaultInstance->GetOrderInParent());
}
obj->PostLoad();
}