Merge remote-tracking branch 'origin/master' into 1.10
# Conflicts: # Source/Engine/Level/Prefabs/Prefab.Apply.cpp
This commit is contained in:
@@ -559,7 +559,7 @@ TEST_CASE("Prefabs")
|
||||
Content::DeleteAsset(prefabNested1);
|
||||
Content::DeleteAsset(prefabBase);
|
||||
}
|
||||
SECTION("Test Applying Prefab ChangeTo Object References")
|
||||
SECTION("Test Applying Prefab Change To Object References")
|
||||
{
|
||||
// https://github.com/FlaxEngine/FlaxEngine/issues/3136
|
||||
|
||||
@@ -614,4 +614,78 @@ TEST_CASE("Prefabs")
|
||||
instanceB->DeleteObject();
|
||||
Content::DeleteAsset(prefab);
|
||||
}
|
||||
SECTION("Test Applying Prefab With Missing Nested Prefab")
|
||||
{
|
||||
// https://github.com/FlaxEngine/FlaxEngine/issues/3244
|
||||
|
||||
// Create Prefab B with just root object
|
||||
AssetReference<Prefab> prefabB = Content::CreateVirtualAsset<Prefab>();
|
||||
REQUIRE(prefabB);
|
||||
Guid id;
|
||||
Guid::Parse("25dbe4b0416be0777a6ce59e8788b10f", id);
|
||||
prefabB->ChangeID(id);
|
||||
auto prefabBInit = prefabB->Init(Prefab::TypeName,
|
||||
"["
|
||||
"{"
|
||||
"\"ID\": \"aac6b9644492fbca1a6ab0a7904a557e\","
|
||||
"\"TypeName\": \"FlaxEngine.ExponentialHeightFog\","
|
||||
"\"Name\": \"Prefab B.Root\""
|
||||
"}"
|
||||
"]");
|
||||
REQUIRE(!prefabBInit);
|
||||
|
||||
// Create Prefab A with nested Prefab B attached to the root
|
||||
AssetReference<Prefab> prefabA = Content::CreateVirtualAsset<Prefab>();
|
||||
REQUIRE(prefabA);
|
||||
Guid::Parse("4cb744714f746e31855f41815612d14b", id);
|
||||
prefabA->ChangeID(id);
|
||||
auto prefabAInit = prefabA->Init(Prefab::TypeName,
|
||||
"["
|
||||
"{"
|
||||
"\"ID\": \"244274a04cc60d56a2f024bfeef5772d\","
|
||||
"\"TypeName\": \"FlaxEngine.SpotLight\","
|
||||
"\"Name\": \"Prefab A.Root\""
|
||||
"},"
|
||||
"{"
|
||||
"\"ID\": \"1e51f1094f430733333f8280e78dfcc3\","
|
||||
"\"PrefabID\": \"25dbe4b0416be0777a6ce59e8788b10f\","
|
||||
"\"PrefabObjectID\": \"aac6b9644492fbca1a6ab0a7904a557e\","
|
||||
"\"ParentID\": \"244274a04cc60d56a2f024bfeef5772d\""
|
||||
"}"
|
||||
"]");
|
||||
REQUIRE(!prefabAInit);
|
||||
|
||||
// Spawn test instances of both prefabs
|
||||
ScriptingObjectReference<Actor> instanceA = PrefabManager::SpawnPrefab(prefabA);
|
||||
ScriptingObjectReference<Actor> instanceB = PrefabManager::SpawnPrefab(prefabB);
|
||||
|
||||
// Delete nested prefab
|
||||
Content::DeleteAsset(prefabB);
|
||||
|
||||
// Apply instance A and verify it's fine even tho prefab B doesn't exist anymore
|
||||
bool applyResult = PrefabManager::ApplyAll(instanceA);
|
||||
REQUIRE(!applyResult);
|
||||
|
||||
// Check state of objects
|
||||
REQUIRE(instanceA);
|
||||
REQUIRE(instanceA->Children.Count() == 1);
|
||||
REQUIRE(instanceA->Children[0] != nullptr);
|
||||
REQUIRE(instanceA->Children[0]->Is<ExponentialHeightFog>());
|
||||
REQUIRE(instanceB);
|
||||
REQUIRE(instanceB->Is<ExponentialHeightFog>());
|
||||
|
||||
// Verify if prefab has new data to properly spawn another prefab
|
||||
ScriptingObjectReference<Actor> instanceC = PrefabManager::SpawnPrefab(prefabA);
|
||||
REQUIRE(instanceC);
|
||||
REQUIRE(instanceC->Children.Count() == 1);
|
||||
REQUIRE(instanceC->Children[0] != nullptr);
|
||||
REQUIRE(instanceC->Children[0]->Is<ExponentialHeightFog>());
|
||||
|
||||
// Cleanup
|
||||
instanceA->DeleteObject();
|
||||
instanceB->DeleteObject();
|
||||
instanceC->DeleteObject();
|
||||
Content::DeleteAsset(prefabA);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include "Engine/Core/Collections/Array.h"
|
||||
#include "Engine/Scripting/ScriptingObject.h"
|
||||
#include "Engine/Scripting/SerializableScriptingObject.h"
|
||||
#include "Engine/Scripting/SoftTypeReference.h"
|
||||
#include "Engine/Content/SceneReference.h"
|
||||
|
||||
// Test default values init on fields.
|
||||
API_STRUCT(NoDefault) struct TestDefaultValues
|
||||
@@ -124,10 +126,17 @@ API_STRUCT(NoDefault) struct TestStruct : public ISerializable
|
||||
API_FIELD() Float3 Vector = Float3::One;
|
||||
// Ref
|
||||
API_FIELD() ScriptingObject* Object = nullptr;
|
||||
// Soft Type Ref
|
||||
API_FIELD() SoftTypeReference<ScriptingObject> SoftTypeRef;
|
||||
// Scene Ref
|
||||
API_FIELD() SceneReference SceneRef;
|
||||
|
||||
friend bool operator==(const TestStruct& lhs, const TestStruct& rhs)
|
||||
{
|
||||
return lhs.Vector == rhs.Vector && lhs.Object == rhs.Object;
|
||||
return lhs.Vector == rhs.Vector &&
|
||||
lhs.Object == rhs.Object &&
|
||||
lhs.SoftTypeRef == rhs.SoftTypeRef &&
|
||||
lhs.SceneRef == rhs.SceneRef;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user