@@ -687,6 +687,171 @@ TEST_CASE("Prefabs")
|
||||
instanceA->DeleteObject();
|
||||
instanceB->DeleteObject();
|
||||
instanceC->DeleteObject();
|
||||
}
|
||||
SECTION("Test Loading Nested Prefab With Multiple Instances of Nested Prefab")
|
||||
{
|
||||
// https://github.com/FlaxEngine/FlaxEngine/issues/3255
|
||||
|
||||
// Create Prefab C with basic cross-object references
|
||||
AssetReference<Prefab> prefabC = Content::CreateVirtualAsset<Prefab>();
|
||||
REQUIRE(prefabC);
|
||||
Guid id;
|
||||
Guid::Parse("cccbe4b0416be0777a6ce59e8788b10f", id);
|
||||
prefabC->ChangeID(id);
|
||||
auto prefabCInit = prefabC->Init(Prefab::TypeName,
|
||||
"["
|
||||
"{"
|
||||
"\"ID\": \"aac6b9644492fbca1a6ab0a7904a557e\","
|
||||
"\"TypeName\": \"FlaxEngine.ExponentialHeightFog\","
|
||||
"\"Name\": \"Prefab C.Root\","
|
||||
"\"DirectionalInscatteringLight\": \"bbb6b9644492fbca1a6ab0a7904a557e\""
|
||||
"},"
|
||||
"{"
|
||||
"\"ID\": \"bbb6b9644492fbca1a6ab0a7904a557e\","
|
||||
"\"TypeName\": \"FlaxEngine.DirectionalLight\","
|
||||
"\"ParentID\": \"aac6b9644492fbca1a6ab0a7904a557e\","
|
||||
"\"Name\": \"Prefab C.Light\""
|
||||
"}"
|
||||
"]");
|
||||
REQUIRE(!prefabCInit);
|
||||
|
||||
// Create Prefab B with two nested Prefab C attached to the root
|
||||
AssetReference<Prefab> prefabB = Content::CreateVirtualAsset<Prefab>();
|
||||
REQUIRE(prefabB);
|
||||
SCOPE_EXIT{ Content::DeleteAsset(prefabB); };
|
||||
Guid::Parse("bbb744714f746e31855f41815612d14b", id);
|
||||
prefabB->ChangeID(id);
|
||||
auto prefabBInit = prefabB->Init(Prefab::TypeName,
|
||||
"["
|
||||
"{"
|
||||
"\"ID\": \"244274a04cc60d56a2f024bfeef5772d\","
|
||||
"\"TypeName\": \"FlaxEngine.SpotLight\","
|
||||
"\"Name\": \"Prefab B.Root\""
|
||||
"},"
|
||||
"{"
|
||||
"\"ID\": \"1111f1094f430733333f8280e78dfcc3\","
|
||||
"\"PrefabID\": \"cccbe4b0416be0777a6ce59e8788b10f\","
|
||||
"\"PrefabObjectID\": \"aac6b9644492fbca1a6ab0a7904a557e\","
|
||||
"\"ParentID\": \"244274a04cc60d56a2f024bfeef5772d\""
|
||||
"},"
|
||||
"{"
|
||||
"\"ID\": \"2221f1094f430733333f8280e78dfcc3\","
|
||||
"\"PrefabID\": \"cccbe4b0416be0777a6ce59e8788b10f\","
|
||||
"\"PrefabObjectID\": \"bbb6b9644492fbca1a6ab0a7904a557e\","
|
||||
"\"ParentID\": \"1111f1094f430733333f8280e78dfcc3\""
|
||||
"},"
|
||||
"{"
|
||||
"\"ID\": \"3331f1094f430733333f8280e78dfcc3\","
|
||||
"\"PrefabID\": \"cccbe4b0416be0777a6ce59e8788b10f\","
|
||||
"\"PrefabObjectID\": \"aac6b9644492fbca1a6ab0a7904a557e\","
|
||||
"\"ParentID\": \"244274a04cc60d56a2f024bfeef5772d\""
|
||||
"},"
|
||||
"{"
|
||||
"\"ID\": \"4441f1094f430733333f8280e78dfcc3\","
|
||||
"\"PrefabID\": \"cccbe4b0416be0777a6ce59e8788b10f\","
|
||||
"\"PrefabObjectID\": \"bbb6b9644492fbca1a6ab0a7904a557e\","
|
||||
"\"ParentID\": \"3331f1094f430733333f8280e78dfcc3\""
|
||||
"}"
|
||||
"]");
|
||||
REQUIRE(!prefabBInit);
|
||||
|
||||
// Create Prefab A as variant of Prefab B (no local changes, just object remapped)
|
||||
AssetReference<Prefab> prefabA = Content::CreateVirtualAsset<Prefab>();
|
||||
REQUIRE(prefabA);
|
||||
SCOPE_EXIT{ Content::DeleteAsset(prefabA); };
|
||||
Guid::Parse("aaa744714f746e31855f41815612d14b", id);
|
||||
prefabA->ChangeID(id);
|
||||
auto prefabAInit = prefabA->Init(Prefab::TypeName,
|
||||
"["
|
||||
"{"
|
||||
"\"ID\": \"123274a04cc60d56a2f024bfeef5772d\","
|
||||
"\"PrefabID\": \"bbb744714f746e31855f41815612d14b\","
|
||||
"\"PrefabObjectID\": \"244274a04cc60d56a2f024bfeef5772d\","
|
||||
"\"Name\": \"Prefab A.Root\""
|
||||
"},"
|
||||
"{"
|
||||
"\"ID\": \"1211f1094f430733333f8280e78dfcc3\","
|
||||
"\"PrefabID\": \"bbb744714f746e31855f41815612d14b\","
|
||||
"\"PrefabObjectID\": \"1111f1094f430733333f8280e78dfcc3\","
|
||||
"\"ParentID\": \"123274a04cc60d56a2f024bfeef5772d\""
|
||||
"},"
|
||||
"{"
|
||||
"\"ID\": \"4221f1094f430733333f8280e78dfcc3\","
|
||||
"\"PrefabID\": \"bbb744714f746e31855f41815612d14b\","
|
||||
"\"PrefabObjectID\": \"2221f1094f430733333f8280e78dfcc3\","
|
||||
"\"ParentID\": \"1211f1094f430733333f8280e78dfcc3\""
|
||||
"},"
|
||||
"{"
|
||||
"\"ID\": \"3131f1094f430733333f8280e78dfcc3\","
|
||||
"\"PrefabID\": \"bbb744714f746e31855f41815612d14b\","
|
||||
"\"PrefabObjectID\": \"3331f1094f430733333f8280e78dfcc3\","
|
||||
"\"ParentID\": \"123274a04cc60d56a2f024bfeef5772d\""
|
||||
"},"
|
||||
"{"
|
||||
"\"ID\": \"5441f1094f430733333f8280e78dfcc3\","
|
||||
"\"PrefabID\": \"bbb744714f746e31855f41815612d14b\","
|
||||
"\"PrefabObjectID\": \"4441f1094f430733333f8280e78dfcc3\","
|
||||
"\"ParentID\": \"3131f1094f430733333f8280e78dfcc3\""
|
||||
"}"
|
||||
"]");
|
||||
REQUIRE(!prefabAInit);
|
||||
|
||||
// Spawn test instances of both prefabs
|
||||
ScriptingObjectReference<Actor> instanceA = PrefabManager::SpawnPrefab(prefabA);
|
||||
ScriptingObjectReference<Actor> instanceB = PrefabManager::SpawnPrefab(prefabB);
|
||||
ScriptingObjectReference<Actor> instanceC = PrefabManager::SpawnPrefab(prefabC);
|
||||
|
||||
// Check state of objects
|
||||
REQUIRE(instanceC);
|
||||
REQUIRE(instanceC->Is<ExponentialHeightFog>());
|
||||
REQUIRE(instanceC->Children.Count() == 1);
|
||||
CHECK(instanceC.As<ExponentialHeightFog>()->DirectionalInscatteringLight == instanceC->Children[0]);
|
||||
REQUIRE(instanceB);
|
||||
REQUIRE(instanceB->Children.Count() == 2);
|
||||
ScriptingObjectReference<Actor> instanceB1 = instanceB->Children[0];
|
||||
ScriptingObjectReference<Actor> instanceB2 = instanceB->Children[1];
|
||||
REQUIRE(instanceB1->Is<ExponentialHeightFog>());
|
||||
REQUIRE(instanceB1->Children.Count() == 1);
|
||||
CHECK(instanceB1.As<ExponentialHeightFog>()->DirectionalInscatteringLight == instanceB1->Children[0]);
|
||||
REQUIRE(instanceB2->Is<ExponentialHeightFog>());
|
||||
REQUIRE(instanceB2->Children.Count() == 1);
|
||||
CHECK(instanceB2.As<ExponentialHeightFog>()->DirectionalInscatteringLight == instanceB2->Children[0]);
|
||||
REQUIRE(instanceA);
|
||||
REQUIRE(instanceA->Children.Count() == 2);
|
||||
ScriptingObjectReference<Actor> instanceA1 = instanceA->Children[0];
|
||||
ScriptingObjectReference<Actor> instanceA2 = instanceA->Children[1];
|
||||
REQUIRE(instanceA1->Is<ExponentialHeightFog>());
|
||||
REQUIRE(instanceA1->Children.Count() == 1);
|
||||
CHECK(instanceA1.As<ExponentialHeightFog>()->DirectionalInscatteringLight == instanceA1->Children[0]);
|
||||
REQUIRE(instanceA2->Is<ExponentialHeightFog>());
|
||||
REQUIRE(instanceA1->Children.Count() == 1);
|
||||
CHECK(instanceA2.As<ExponentialHeightFog>()->DirectionalInscatteringLight == instanceA2->Children[0]);
|
||||
|
||||
// Add instance of Prefab C to Prefab B
|
||||
instanceC->SetName(StringView(TEXT("New")));
|
||||
instanceC->SetParent(instanceB);
|
||||
bool applyResult = PrefabManager::ApplyAll(instanceB);
|
||||
REQUIRE(!applyResult);
|
||||
|
||||
// Check if Prefab A reflects that change
|
||||
REQUIRE(instanceA);
|
||||
REQUIRE(instanceA->Children.Count() == 3);
|
||||
instanceA1 = instanceA->Children[0];
|
||||
instanceA2 = instanceA->Children[1];
|
||||
ScriptingObjectReference<Actor> instanceA3 = instanceA->Children[2];
|
||||
REQUIRE(instanceA1->Is<ExponentialHeightFog>());
|
||||
REQUIRE(instanceA1->Children.Count() == 1);
|
||||
CHECK(instanceA1.As<ExponentialHeightFog>()->DirectionalInscatteringLight == instanceA1->Children[0]);
|
||||
REQUIRE(instanceA2->Is<ExponentialHeightFog>());
|
||||
REQUIRE(instanceA2->Children.Count() == 1);
|
||||
CHECK(instanceA2.As<ExponentialHeightFog>()->DirectionalInscatteringLight == instanceA2->Children[0]);
|
||||
REQUIRE(instanceA3->Is<ExponentialHeightFog>());
|
||||
REQUIRE(instanceA3->Children.Count() == 1);
|
||||
CHECK(instanceA3.As<ExponentialHeightFog>()->DirectionalInscatteringLight == instanceA3->Children[0]);
|
||||
|
||||
// Cleanup
|
||||
instanceA->DeleteObject();
|
||||
instanceB->DeleteObject();
|
||||
instanceC->DeleteObject();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user