Align Unity-style object and hierarchy scripting APIs

This commit is contained in:
2026-04-03 14:31:07 +08:00
parent 9edf378085
commit 5225faff1d
10 changed files with 765 additions and 22 deletions

View File

@@ -1920,6 +1920,89 @@ TEST_F(MonoScriptRuntimeTest, TransformHierarchyApiExposesParentChildAndReparent
EXPECT_EQ(reparentTarget->GetChildCount(), 1u);
}
TEST_F(MonoScriptRuntimeTest, UnityObjectApiSupportsHierarchyLookupAndDestroy) {
Scene* runtimeScene = CreateScene("MonoRuntimeScene");
GameObject* root = runtimeScene->CreateGameObject("Root");
GameObject* host = runtimeScene->CreateGameObject("Host", root);
GameObject* child = runtimeScene->CreateGameObject("Child", host);
root->AddComponent<CameraComponent>();
child->AddComponent<CameraComponent>();
child->AddComponent<MeshRendererComponent>();
AddScript(root, "Gameplay", "ObjectApiMarkerProbe");
AddScript(child, "Gameplay", "ObjectApiDestroyTargetProbe");
ScriptComponent* hostProbe = AddScript(host, "Gameplay", "ObjectApiProbe");
engine->OnRuntimeStart(runtimeScene);
engine->OnUpdate(0.016f);
bool foundSelfScriptViaParentLookup = false;
bool foundSelfScriptViaGameObjectParentLookup = false;
bool foundSelfTransformViaChildrenLookup = false;
bool foundSelfTransformViaGameObjectChildrenLookup = false;
bool foundCameraInParent = false;
bool foundCameraInParentViaGameObject = false;
bool foundMarkerInParent = false;
bool foundMeshRendererInChildren = false;
bool foundMeshRendererInChildrenViaGameObject = false;
bool foundTargetScriptInChildren = false;
bool childCameraMissingAfterDestroy = false;
bool childScriptMissingAfterDestroy = false;
bool childGameObjectMissingAfterDestroy = false;
int32_t observedChildScriptDisableCount = -1;
int32_t observedChildCountAfterDestroy = -1;
std::string observedParentCameraHostName;
std::string observedChildMeshRendererHostName;
std::string observedChildScriptHostName;
EXPECT_TRUE(runtime->TryGetFieldValue(hostProbe, "FoundSelfScriptViaParentLookup", foundSelfScriptViaParentLookup));
EXPECT_TRUE(runtime->TryGetFieldValue(hostProbe, "FoundSelfScriptViaGameObjectParentLookup", foundSelfScriptViaGameObjectParentLookup));
EXPECT_TRUE(runtime->TryGetFieldValue(hostProbe, "FoundSelfTransformViaChildrenLookup", foundSelfTransformViaChildrenLookup));
EXPECT_TRUE(runtime->TryGetFieldValue(hostProbe, "FoundSelfTransformViaGameObjectChildrenLookup", foundSelfTransformViaGameObjectChildrenLookup));
EXPECT_TRUE(runtime->TryGetFieldValue(hostProbe, "FoundCameraInParent", foundCameraInParent));
EXPECT_TRUE(runtime->TryGetFieldValue(hostProbe, "FoundCameraInParentViaGameObject", foundCameraInParentViaGameObject));
EXPECT_TRUE(runtime->TryGetFieldValue(hostProbe, "FoundMarkerInParent", foundMarkerInParent));
EXPECT_TRUE(runtime->TryGetFieldValue(hostProbe, "FoundMeshRendererInChildren", foundMeshRendererInChildren));
EXPECT_TRUE(runtime->TryGetFieldValue(hostProbe, "FoundMeshRendererInChildrenViaGameObject", foundMeshRendererInChildrenViaGameObject));
EXPECT_TRUE(runtime->TryGetFieldValue(hostProbe, "FoundTargetScriptInChildren", foundTargetScriptInChildren));
EXPECT_TRUE(runtime->TryGetFieldValue(hostProbe, "ChildCameraMissingAfterDestroy", childCameraMissingAfterDestroy));
EXPECT_TRUE(runtime->TryGetFieldValue(hostProbe, "ChildScriptMissingAfterDestroy", childScriptMissingAfterDestroy));
EXPECT_TRUE(runtime->TryGetFieldValue(hostProbe, "ChildGameObjectMissingAfterDestroy", childGameObjectMissingAfterDestroy));
EXPECT_TRUE(runtime->TryGetFieldValue(hostProbe, "ObservedChildScriptDisableCount", observedChildScriptDisableCount));
EXPECT_TRUE(runtime->TryGetFieldValue(hostProbe, "ObservedChildCountAfterDestroy", observedChildCountAfterDestroy));
EXPECT_TRUE(runtime->TryGetFieldValue(hostProbe, "ObservedParentCameraHostName", observedParentCameraHostName));
EXPECT_TRUE(runtime->TryGetFieldValue(hostProbe, "ObservedChildMeshRendererHostName", observedChildMeshRendererHostName));
EXPECT_TRUE(runtime->TryGetFieldValue(hostProbe, "ObservedChildScriptHostName", observedChildScriptHostName));
EXPECT_TRUE(foundSelfScriptViaParentLookup);
EXPECT_TRUE(foundSelfScriptViaGameObjectParentLookup);
EXPECT_TRUE(foundSelfTransformViaChildrenLookup);
EXPECT_TRUE(foundSelfTransformViaGameObjectChildrenLookup);
EXPECT_TRUE(foundCameraInParent);
EXPECT_TRUE(foundCameraInParentViaGameObject);
EXPECT_TRUE(foundMarkerInParent);
EXPECT_TRUE(foundMeshRendererInChildren);
EXPECT_TRUE(foundMeshRendererInChildrenViaGameObject);
EXPECT_TRUE(foundTargetScriptInChildren);
EXPECT_TRUE(childCameraMissingAfterDestroy);
EXPECT_TRUE(childScriptMissingAfterDestroy);
EXPECT_TRUE(childGameObjectMissingAfterDestroy);
EXPECT_EQ(observedChildScriptDisableCount, 1);
EXPECT_EQ(observedChildCountAfterDestroy, 0);
EXPECT_EQ(observedParentCameraHostName, "Root");
EXPECT_EQ(observedChildMeshRendererHostName, "Child");
EXPECT_EQ(observedChildScriptHostName, "Child");
EXPECT_EQ(runtimeScene->Find("Child"), nullptr);
EXPECT_EQ(host->GetChildCount(), 0u);
EXPECT_EQ(host->GetComponentInChildren<CameraComponent>(), nullptr);
EXPECT_EQ(host->GetComponentInChildren<MeshRendererComponent>(), nullptr);
EXPECT_EQ(host->GetComponents<ScriptComponent>().size(), 1u);
EXPECT_EQ(root->GetComponents<ScriptComponent>().size(), 1u);
EXPECT_EQ(runtime->GetManagedInstanceCount(), 2u);
}
TEST_F(MonoScriptRuntimeTest, TransformSpaceApiReadsAndWritesWorldAndLocalValues) {
Scene* runtimeScene = CreateScene("MonoRuntimeScene");
GameObject* parent = runtimeScene->CreateGameObject("Parent");