feat(scripting): add script add-component api
This commit is contained in:
@@ -15,14 +15,20 @@ std::string ToStdString(const Containers::String& value) {
|
||||
|
||||
std::vector<std::string> SplitMaterialPaths(const std::string& value) {
|
||||
std::vector<std::string> paths;
|
||||
std::stringstream stream(value);
|
||||
std::string item;
|
||||
while (std::getline(stream, item, '|')) {
|
||||
paths.push_back(item);
|
||||
if (value.empty()) {
|
||||
return paths;
|
||||
}
|
||||
|
||||
if (value.empty()) {
|
||||
paths.clear();
|
||||
size_t start = 0;
|
||||
while (true) {
|
||||
const size_t separator = value.find('|', start);
|
||||
if (separator == std::string::npos) {
|
||||
paths.push_back(value.substr(start));
|
||||
break;
|
||||
}
|
||||
|
||||
paths.push_back(value.substr(start, separator - start));
|
||||
start = separator + 1;
|
||||
}
|
||||
|
||||
return paths;
|
||||
|
||||
@@ -221,6 +221,37 @@ bool HasNativeComponent(Components::GameObject* gameObject, ManagedComponentKind
|
||||
return false;
|
||||
}
|
||||
|
||||
Components::Component* AddOrGetNativeComponent(Components::GameObject* gameObject, ManagedComponentKind componentKind) {
|
||||
if (!gameObject) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
switch (componentKind) {
|
||||
case ManagedComponentKind::Transform:
|
||||
return gameObject->GetTransform();
|
||||
case ManagedComponentKind::Camera:
|
||||
return gameObject->GetComponent<Components::CameraComponent>()
|
||||
? static_cast<Components::Component*>(gameObject->GetComponent<Components::CameraComponent>())
|
||||
: static_cast<Components::Component*>(gameObject->AddComponent<Components::CameraComponent>());
|
||||
case ManagedComponentKind::Light:
|
||||
return gameObject->GetComponent<Components::LightComponent>()
|
||||
? static_cast<Components::Component*>(gameObject->GetComponent<Components::LightComponent>())
|
||||
: static_cast<Components::Component*>(gameObject->AddComponent<Components::LightComponent>());
|
||||
case ManagedComponentKind::MeshFilter:
|
||||
return gameObject->GetComponent<Components::MeshFilterComponent>()
|
||||
? static_cast<Components::Component*>(gameObject->GetComponent<Components::MeshFilterComponent>())
|
||||
: static_cast<Components::Component*>(gameObject->AddComponent<Components::MeshFilterComponent>());
|
||||
case ManagedComponentKind::MeshRenderer:
|
||||
return gameObject->GetComponent<Components::MeshRendererComponent>()
|
||||
? static_cast<Components::Component*>(gameObject->GetComponent<Components::MeshRendererComponent>())
|
||||
: static_cast<Components::Component*>(gameObject->AddComponent<Components::MeshRendererComponent>());
|
||||
case ManagedComponentKind::Unknown:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Components::CameraComponent* FindCameraComponent(uint64_t gameObjectUUID) {
|
||||
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
||||
return gameObject ? gameObject->GetComponent<Components::CameraComponent>() : nullptr;
|
||||
@@ -318,6 +349,11 @@ uint64_t InternalCall_GameObject_GetComponent(uint64_t gameObjectUUID, MonoRefle
|
||||
return gameObjectUUID;
|
||||
}
|
||||
|
||||
uint64_t InternalCall_GameObject_AddComponent(uint64_t gameObjectUUID, MonoReflectionType* componentType) {
|
||||
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
||||
return AddOrGetNativeComponent(gameObject, ResolveManagedComponentKind(componentType)) ? gameObjectUUID : 0;
|
||||
}
|
||||
|
||||
mono_bool InternalCall_Behaviour_GetEnabled(uint64_t scriptComponentUUID) {
|
||||
ScriptComponent* component = FindScriptComponentByUUID(scriptComponentUUID);
|
||||
return (component && component->IsEnabled()) ? 1 : 0;
|
||||
@@ -955,6 +991,7 @@ void RegisterInternalCalls() {
|
||||
mono_add_internal_call("XCEngine.InternalCalls::GameObject_SetActive", reinterpret_cast<const void*>(&InternalCall_GameObject_SetActive));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::GameObject_HasComponent", reinterpret_cast<const void*>(&InternalCall_GameObject_HasComponent));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::GameObject_GetComponent", reinterpret_cast<const void*>(&InternalCall_GameObject_GetComponent));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::GameObject_AddComponent", reinterpret_cast<const void*>(&InternalCall_GameObject_AddComponent));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Behaviour_GetEnabled", reinterpret_cast<const void*>(&InternalCall_Behaviour_GetEnabled));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Behaviour_SetEnabled", reinterpret_cast<const void*>(&InternalCall_Behaviour_SetEnabled));
|
||||
mono_add_internal_call("XCEngine.InternalCalls::Transform_GetLocalPosition", reinterpret_cast<const void*>(&InternalCall_Transform_GetLocalPosition));
|
||||
|
||||
@@ -71,9 +71,11 @@ set(XCENGINE_SCRIPT_CORE_SOURCES
|
||||
|
||||
set(XCENGINE_GAME_SCRIPT_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GameScripts/BuiltinComponentProbe.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GameScripts/AddComponentProbe.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GameScripts/HierarchyProbe.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GameScripts/LifecycleProbe.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GameScripts/MeshComponentProbe.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GameScripts/MeshRendererEdgeCaseProbe.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GameScripts/TransformConversionProbe.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GameScripts/TransformMotionProbe.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GameScripts/TransformOrientationProbe.cs
|
||||
@@ -134,3 +136,4 @@ add_custom_target(
|
||||
${XCENGINE_GAME_SCRIPTS_DLL}
|
||||
${XCENGINE_MANAGED_OUTPUT_DIR}/mscorlib.dll
|
||||
)
|
||||
|
||||
|
||||
87
managed/GameScripts/AddComponentProbe.cs
Normal file
87
managed/GameScripts/AddComponentProbe.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using XCEngine;
|
||||
|
||||
namespace Gameplay
|
||||
{
|
||||
public sealed class AddComponentProbe : MonoBehaviour
|
||||
{
|
||||
public bool InitialHasCamera;
|
||||
public bool InitialHasLight;
|
||||
public bool InitialHasMeshFilter;
|
||||
public bool InitialHasMeshRenderer;
|
||||
public bool AddedTransform;
|
||||
public bool AddedCamera;
|
||||
public bool AddedLight;
|
||||
public bool AddedMeshFilter;
|
||||
public bool AddedMeshRenderer;
|
||||
public bool HasCameraAfterAdd;
|
||||
public bool HasLightAfterAdd;
|
||||
public bool HasMeshFilterAfterAdd;
|
||||
public bool HasMeshRendererAfterAdd;
|
||||
public bool CameraLookupSucceeded;
|
||||
public bool LightLookupSucceeded;
|
||||
public bool MeshFilterLookupSucceeded;
|
||||
public bool MeshRendererLookupSucceeded;
|
||||
public float ObservedCameraFieldOfView;
|
||||
public float ObservedLightIntensity;
|
||||
public string ObservedMeshPath = string.Empty;
|
||||
public int ObservedMaterialCount;
|
||||
public string ObservedMaterial0Path = string.Empty;
|
||||
public int ObservedRenderLayer;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
InitialHasCamera = HasComponent<Camera>();
|
||||
InitialHasLight = HasComponent<Light>();
|
||||
InitialHasMeshFilter = HasComponent<MeshFilter>();
|
||||
InitialHasMeshRenderer = HasComponent<MeshRenderer>();
|
||||
|
||||
AddedTransform = AddComponent<Transform>() != null;
|
||||
AddedCamera = AddComponent<Camera>() != null;
|
||||
AddedLight = gameObject.AddComponent<Light>() != null;
|
||||
AddedMeshFilter = AddComponent<MeshFilter>() != null;
|
||||
AddedMeshRenderer = gameObject.AddComponent<MeshRenderer>() != null;
|
||||
|
||||
gameObject.AddComponent<Camera>();
|
||||
AddComponent<Light>();
|
||||
gameObject.AddComponent<MeshFilter>();
|
||||
AddComponent<MeshRenderer>();
|
||||
|
||||
HasCameraAfterAdd = HasComponent<Camera>();
|
||||
HasLightAfterAdd = HasComponent<Light>();
|
||||
HasMeshFilterAfterAdd = HasComponent<MeshFilter>();
|
||||
HasMeshRendererAfterAdd = HasComponent<MeshRenderer>();
|
||||
|
||||
CameraLookupSucceeded = TryGetComponent(out Camera camera);
|
||||
LightLookupSucceeded = TryGetComponent(out Light light);
|
||||
MeshFilterLookupSucceeded = TryGetComponent(out MeshFilter meshFilter);
|
||||
MeshRendererLookupSucceeded = TryGetComponent(out MeshRenderer meshRenderer);
|
||||
|
||||
if (camera != null)
|
||||
{
|
||||
camera.fieldOfView = 82.0f;
|
||||
ObservedCameraFieldOfView = camera.fieldOfView;
|
||||
}
|
||||
|
||||
if (light != null)
|
||||
{
|
||||
light.intensity = 4.5f;
|
||||
ObservedLightIntensity = light.intensity;
|
||||
}
|
||||
|
||||
if (meshFilter != null)
|
||||
{
|
||||
meshFilter.meshPath = "Meshes/added.mesh";
|
||||
ObservedMeshPath = meshFilter.meshPath;
|
||||
}
|
||||
|
||||
if (meshRenderer != null)
|
||||
{
|
||||
meshRenderer.SetMaterialPath(0, "Materials/added.mat");
|
||||
meshRenderer.renderLayer = 6;
|
||||
ObservedMaterialCount = meshRenderer.materialCount;
|
||||
ObservedMaterial0Path = meshRenderer.GetMaterialPath(0);
|
||||
ObservedRenderLayer = meshRenderer.renderLayer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
51
managed/GameScripts/MeshRendererEdgeCaseProbe.cs
Normal file
51
managed/GameScripts/MeshRendererEdgeCaseProbe.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using XCEngine;
|
||||
|
||||
namespace Gameplay
|
||||
{
|
||||
public sealed class MeshRendererEdgeCaseProbe : MonoBehaviour
|
||||
{
|
||||
public int ObservedInitialMaterialCount;
|
||||
public string ObservedNegativeIndexPath = string.Empty;
|
||||
public string ObservedOutOfRangePathBeforeClear = string.Empty;
|
||||
public string ObservedMaterial0PathAfterNegativeWrite = string.Empty;
|
||||
public string ObservedMaterial1PathAfterNegativeWrite = string.Empty;
|
||||
public int ObservedMaterialCountAfterNegativeWrite;
|
||||
public int ObservedRenderLayerAfterNegativeWrite;
|
||||
public int ObservedMaterialCountAfterClear;
|
||||
public string ObservedMaterial0PathAfterClear = string.Empty;
|
||||
public string ObservedMaterial3PathAfterClear = string.Empty;
|
||||
public bool ObservedCastShadowsAfterClear;
|
||||
public bool ObservedReceiveShadowsAfterClear;
|
||||
public int ObservedRenderLayerAfterClear;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
if (!TryGetComponent(out MeshRenderer meshRenderer) || meshRenderer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ObservedInitialMaterialCount = meshRenderer.materialCount;
|
||||
ObservedNegativeIndexPath = meshRenderer.GetMaterialPath(-1);
|
||||
ObservedOutOfRangePathBeforeClear = meshRenderer.GetMaterialPath(3);
|
||||
|
||||
meshRenderer.SetMaterialPath(-1, "Materials/ignored.mat");
|
||||
|
||||
ObservedMaterial0PathAfterNegativeWrite = meshRenderer.GetMaterialPath(0);
|
||||
ObservedMaterial1PathAfterNegativeWrite = meshRenderer.GetMaterialPath(1);
|
||||
ObservedMaterialCountAfterNegativeWrite = meshRenderer.materialCount;
|
||||
|
||||
meshRenderer.renderLayer = -5;
|
||||
ObservedRenderLayerAfterNegativeWrite = meshRenderer.renderLayer;
|
||||
|
||||
meshRenderer.ClearMaterials();
|
||||
|
||||
ObservedMaterialCountAfterClear = meshRenderer.materialCount;
|
||||
ObservedMaterial0PathAfterClear = meshRenderer.GetMaterialPath(0);
|
||||
ObservedMaterial3PathAfterClear = meshRenderer.GetMaterialPath(3);
|
||||
ObservedCastShadowsAfterClear = meshRenderer.castShadows;
|
||||
ObservedReceiveShadowsAfterClear = meshRenderer.receiveShadows;
|
||||
ObservedRenderLayerAfterClear = meshRenderer.renderLayer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,11 @@ namespace XCEngine
|
||||
return GameObject.GetComponent<T>();
|
||||
}
|
||||
|
||||
public T AddComponent<T>() where T : Component
|
||||
{
|
||||
return GameObject.AddComponent<T>();
|
||||
}
|
||||
|
||||
public bool TryGetComponent<T>(out T component) where T : Component
|
||||
{
|
||||
component = GetComponent<T>();
|
||||
|
||||
@@ -46,6 +46,12 @@ namespace XCEngine
|
||||
return Component.Create<T>(componentOwnerUUID);
|
||||
}
|
||||
|
||||
public T AddComponent<T>() where T : Component
|
||||
{
|
||||
ulong componentOwnerUUID = InternalCalls.GameObject_AddComponent(UUID, typeof(T));
|
||||
return Component.Create<T>(componentOwnerUUID);
|
||||
}
|
||||
|
||||
public bool TryGetComponent<T>(out T component) where T : Component
|
||||
{
|
||||
component = GetComponent<T>();
|
||||
|
||||
@@ -38,6 +38,9 @@ namespace XCEngine
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern ulong GameObject_GetComponent(ulong gameObjectUUID, Type componentType);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern ulong GameObject_AddComponent(ulong gameObjectUUID, Type componentType);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern bool Behaviour_GetEnabled(ulong scriptComponentUUID);
|
||||
|
||||
|
||||
@@ -135,6 +135,34 @@ TEST(MeshRendererComponent_Test, SerializeAndDeserializePreservesMaterialPathsAn
|
||||
delete material1;
|
||||
}
|
||||
|
||||
TEST(MeshRendererComponent_Test, SerializeAndDeserializePreservesTrailingEmptyMaterialSlots) {
|
||||
MeshRendererComponent source;
|
||||
Material* material0 = CreateTestMaterial("M0", "Materials/serialized0.mat");
|
||||
source.SetMaterial(0, material0);
|
||||
source.SetMaterialPath(1, "");
|
||||
source.SetCastShadows(false);
|
||||
source.SetReceiveShadows(true);
|
||||
source.SetRenderLayer(9);
|
||||
|
||||
std::stringstream stream;
|
||||
source.Serialize(stream);
|
||||
|
||||
MeshRendererComponent target;
|
||||
target.Deserialize(stream);
|
||||
|
||||
ASSERT_EQ(target.GetMaterialCount(), 2u);
|
||||
EXPECT_EQ(target.GetMaterial(0), nullptr);
|
||||
EXPECT_EQ(target.GetMaterial(1), nullptr);
|
||||
EXPECT_EQ(target.GetMaterialPath(0), "Materials/serialized0.mat");
|
||||
EXPECT_EQ(target.GetMaterialPath(1), "");
|
||||
EXPECT_FALSE(target.GetCastShadows());
|
||||
EXPECT_TRUE(target.GetReceiveShadows());
|
||||
EXPECT_EQ(target.GetRenderLayer(), 9u);
|
||||
|
||||
source.ClearMaterials();
|
||||
delete material0;
|
||||
}
|
||||
|
||||
TEST(MeshRendererComponent_Test, SetMaterialPathPreservesPathWithoutLoadedResource) {
|
||||
MeshRendererComponent component;
|
||||
|
||||
|
||||
@@ -393,6 +393,175 @@ TEST_F(MonoScriptRuntimeTest, ManagedMeshComponentWrappersReadAndWritePathsAndFl
|
||||
EXPECT_EQ(meshRenderer->GetRenderLayer(), 11u);
|
||||
}
|
||||
|
||||
TEST_F(MonoScriptRuntimeTest, ManagedMeshRendererWrapperHandlesClearAndBoundaryCases) {
|
||||
Scene* runtimeScene = CreateScene("MonoRuntimeScene");
|
||||
GameObject* host = runtimeScene->CreateGameObject("Host");
|
||||
MeshRendererComponent* meshRenderer = host->AddComponent<MeshRendererComponent>();
|
||||
ScriptComponent* component = AddScript(host, "Gameplay", "MeshRendererEdgeCaseProbe");
|
||||
|
||||
meshRenderer->SetMaterialPath(0, "Materials/initial0.mat");
|
||||
meshRenderer->SetMaterialPath(1, "Materials/initial1.mat");
|
||||
meshRenderer->SetCastShadows(false);
|
||||
meshRenderer->SetReceiveShadows(true);
|
||||
meshRenderer->SetRenderLayer(9);
|
||||
|
||||
engine->OnRuntimeStart(runtimeScene);
|
||||
engine->OnUpdate(0.016f);
|
||||
|
||||
int32_t observedInitialMaterialCount = 0;
|
||||
std::string observedNegativeIndexPath;
|
||||
std::string observedOutOfRangePathBeforeClear;
|
||||
std::string observedMaterial0PathAfterNegativeWrite;
|
||||
std::string observedMaterial1PathAfterNegativeWrite;
|
||||
int32_t observedMaterialCountAfterNegativeWrite = 0;
|
||||
int32_t observedRenderLayerAfterNegativeWrite = -1;
|
||||
int32_t observedMaterialCountAfterClear = -1;
|
||||
std::string observedMaterial0PathAfterClear;
|
||||
std::string observedMaterial3PathAfterClear;
|
||||
bool observedCastShadowsAfterClear = true;
|
||||
bool observedReceiveShadowsAfterClear = false;
|
||||
int32_t observedRenderLayerAfterClear = -1;
|
||||
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedInitialMaterialCount", observedInitialMaterialCount));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedNegativeIndexPath", observedNegativeIndexPath));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedOutOfRangePathBeforeClear", observedOutOfRangePathBeforeClear));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedMaterial0PathAfterNegativeWrite", observedMaterial0PathAfterNegativeWrite));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedMaterial1PathAfterNegativeWrite", observedMaterial1PathAfterNegativeWrite));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedMaterialCountAfterNegativeWrite", observedMaterialCountAfterNegativeWrite));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedRenderLayerAfterNegativeWrite", observedRenderLayerAfterNegativeWrite));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedMaterialCountAfterClear", observedMaterialCountAfterClear));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedMaterial0PathAfterClear", observedMaterial0PathAfterClear));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedMaterial3PathAfterClear", observedMaterial3PathAfterClear));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedCastShadowsAfterClear", observedCastShadowsAfterClear));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedReceiveShadowsAfterClear", observedReceiveShadowsAfterClear));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedRenderLayerAfterClear", observedRenderLayerAfterClear));
|
||||
|
||||
EXPECT_EQ(observedInitialMaterialCount, 2);
|
||||
EXPECT_EQ(observedNegativeIndexPath, "");
|
||||
EXPECT_EQ(observedOutOfRangePathBeforeClear, "");
|
||||
EXPECT_EQ(observedMaterial0PathAfterNegativeWrite, "Materials/initial0.mat");
|
||||
EXPECT_EQ(observedMaterial1PathAfterNegativeWrite, "Materials/initial1.mat");
|
||||
EXPECT_EQ(observedMaterialCountAfterNegativeWrite, 2);
|
||||
EXPECT_EQ(observedRenderLayerAfterNegativeWrite, 0);
|
||||
EXPECT_EQ(observedMaterialCountAfterClear, 0);
|
||||
EXPECT_EQ(observedMaterial0PathAfterClear, "");
|
||||
EXPECT_EQ(observedMaterial3PathAfterClear, "");
|
||||
EXPECT_FALSE(observedCastShadowsAfterClear);
|
||||
EXPECT_TRUE(observedReceiveShadowsAfterClear);
|
||||
EXPECT_EQ(observedRenderLayerAfterClear, 0);
|
||||
|
||||
EXPECT_EQ(meshRenderer->GetMaterialCount(), 0u);
|
||||
EXPECT_EQ(meshRenderer->GetMaterialPath(0), "");
|
||||
EXPECT_EQ(meshRenderer->GetMaterialPath(3), "");
|
||||
EXPECT_FALSE(meshRenderer->GetCastShadows());
|
||||
EXPECT_TRUE(meshRenderer->GetReceiveShadows());
|
||||
EXPECT_EQ(meshRenderer->GetRenderLayer(), 0u);
|
||||
}
|
||||
|
||||
TEST_F(MonoScriptRuntimeTest, GameObjectAddComponentApiCreatesBuiltinComponentsAndAvoidsDuplicates) {
|
||||
Scene* runtimeScene = CreateScene("MonoRuntimeScene");
|
||||
GameObject* host = runtimeScene->CreateGameObject("Host");
|
||||
ScriptComponent* component = AddScript(host, "Gameplay", "AddComponentProbe");
|
||||
|
||||
engine->OnRuntimeStart(runtimeScene);
|
||||
engine->OnUpdate(0.016f);
|
||||
|
||||
bool initialHasCamera = true;
|
||||
bool initialHasLight = true;
|
||||
bool initialHasMeshFilter = true;
|
||||
bool initialHasMeshRenderer = true;
|
||||
bool addedTransform = false;
|
||||
bool addedCamera = false;
|
||||
bool addedLight = false;
|
||||
bool addedMeshFilter = false;
|
||||
bool addedMeshRenderer = false;
|
||||
bool hasCameraAfterAdd = false;
|
||||
bool hasLightAfterAdd = false;
|
||||
bool hasMeshFilterAfterAdd = false;
|
||||
bool hasMeshRendererAfterAdd = false;
|
||||
bool cameraLookupSucceeded = false;
|
||||
bool lightLookupSucceeded = false;
|
||||
bool meshFilterLookupSucceeded = false;
|
||||
bool meshRendererLookupSucceeded = false;
|
||||
float observedCameraFieldOfView = 0.0f;
|
||||
float observedLightIntensity = 0.0f;
|
||||
std::string observedMeshPath;
|
||||
int32_t observedMaterialCount = 0;
|
||||
std::string observedMaterial0Path;
|
||||
int32_t observedRenderLayer = 0;
|
||||
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "InitialHasCamera", initialHasCamera));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "InitialHasLight", initialHasLight));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "InitialHasMeshFilter", initialHasMeshFilter));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "InitialHasMeshRenderer", initialHasMeshRenderer));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "AddedTransform", addedTransform));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "AddedCamera", addedCamera));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "AddedLight", addedLight));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "AddedMeshFilter", addedMeshFilter));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "AddedMeshRenderer", addedMeshRenderer));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "HasCameraAfterAdd", hasCameraAfterAdd));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "HasLightAfterAdd", hasLightAfterAdd));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "HasMeshFilterAfterAdd", hasMeshFilterAfterAdd));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "HasMeshRendererAfterAdd", hasMeshRendererAfterAdd));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "CameraLookupSucceeded", cameraLookupSucceeded));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "LightLookupSucceeded", lightLookupSucceeded));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "MeshFilterLookupSucceeded", meshFilterLookupSucceeded));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "MeshRendererLookupSucceeded", meshRendererLookupSucceeded));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedCameraFieldOfView", observedCameraFieldOfView));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedLightIntensity", observedLightIntensity));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedMeshPath", observedMeshPath));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedMaterialCount", observedMaterialCount));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedMaterial0Path", observedMaterial0Path));
|
||||
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedRenderLayer", observedRenderLayer));
|
||||
|
||||
EXPECT_FALSE(initialHasCamera);
|
||||
EXPECT_FALSE(initialHasLight);
|
||||
EXPECT_FALSE(initialHasMeshFilter);
|
||||
EXPECT_FALSE(initialHasMeshRenderer);
|
||||
EXPECT_TRUE(addedTransform);
|
||||
EXPECT_TRUE(addedCamera);
|
||||
EXPECT_TRUE(addedLight);
|
||||
EXPECT_TRUE(addedMeshFilter);
|
||||
EXPECT_TRUE(addedMeshRenderer);
|
||||
EXPECT_TRUE(hasCameraAfterAdd);
|
||||
EXPECT_TRUE(hasLightAfterAdd);
|
||||
EXPECT_TRUE(hasMeshFilterAfterAdd);
|
||||
EXPECT_TRUE(hasMeshRendererAfterAdd);
|
||||
EXPECT_TRUE(cameraLookupSucceeded);
|
||||
EXPECT_TRUE(lightLookupSucceeded);
|
||||
EXPECT_TRUE(meshFilterLookupSucceeded);
|
||||
EXPECT_TRUE(meshRendererLookupSucceeded);
|
||||
EXPECT_FLOAT_EQ(observedCameraFieldOfView, 82.0f);
|
||||
EXPECT_FLOAT_EQ(observedLightIntensity, 4.5f);
|
||||
EXPECT_EQ(observedMeshPath, "Meshes/added.mesh");
|
||||
EXPECT_EQ(observedMaterialCount, 1);
|
||||
EXPECT_EQ(observedMaterial0Path, "Materials/added.mat");
|
||||
EXPECT_EQ(observedRenderLayer, 6);
|
||||
|
||||
ASSERT_NE(host->GetTransform(), nullptr);
|
||||
EXPECT_EQ(host->GetComponents<CameraComponent>().size(), 1u);
|
||||
EXPECT_EQ(host->GetComponents<LightComponent>().size(), 1u);
|
||||
EXPECT_EQ(host->GetComponents<MeshFilterComponent>().size(), 1u);
|
||||
EXPECT_EQ(host->GetComponents<MeshRendererComponent>().size(), 1u);
|
||||
|
||||
CameraComponent* camera = host->GetComponent<CameraComponent>();
|
||||
LightComponent* light = host->GetComponent<LightComponent>();
|
||||
MeshFilterComponent* meshFilter = host->GetComponent<MeshFilterComponent>();
|
||||
MeshRendererComponent* meshRenderer = host->GetComponent<MeshRendererComponent>();
|
||||
|
||||
ASSERT_NE(camera, nullptr);
|
||||
ASSERT_NE(light, nullptr);
|
||||
ASSERT_NE(meshFilter, nullptr);
|
||||
ASSERT_NE(meshRenderer, nullptr);
|
||||
|
||||
EXPECT_FLOAT_EQ(camera->GetFieldOfView(), 82.0f);
|
||||
EXPECT_FLOAT_EQ(light->GetIntensity(), 4.5f);
|
||||
EXPECT_EQ(meshFilter->GetMeshPath(), "Meshes/added.mesh");
|
||||
ASSERT_EQ(meshRenderer->GetMaterialCount(), 1u);
|
||||
EXPECT_EQ(meshRenderer->GetMaterialPath(0), "Materials/added.mat");
|
||||
EXPECT_EQ(meshRenderer->GetRenderLayer(), 6u);
|
||||
}
|
||||
|
||||
TEST_F(MonoScriptRuntimeTest, TransformHierarchyApiExposesParentChildAndReparenting) {
|
||||
Scene* runtimeScene = CreateScene("MonoRuntimeScene");
|
||||
GameObject* root = runtimeScene->CreateGameObject("Root");
|
||||
|
||||
Reference in New Issue
Block a user