fix: guard TransformHandle against reflection serialization (destroyed-object NRE) - #1274
fix: guard TransformHandle against reflection serialization (destroyed-object NRE)#1274agudmund wants to merge 1 commit into
Conversation
GameObjectSerializer reflects over component properties and hands values to Json.NET. On Unity 6, a property returning UnityEngine.TransformHandle makes the serializer enumerate the handle's direct children - which throws NullReferenceException (AssertHandleIsValid) the moment the underlying object is destroyed, a common race when component data is read during play mode while scripts Destroy() objects. On live objects it would walk entire child hierarchies of handles instead of a value. Add a write-only TransformHandleConverter that emits null for the type, matched by full name so the package still compiles on Unity versions without the type (floor is 2021.3), avoiding version defines per the Unity*Compat guidance. Internal for the same converter-scanner reason as UnityEngineObjectConverter (CoplayDev#1138). Repro: read mcpforunity://scene/gameobject/{id}/components repeatedly in play mode while a spawner destroys and respawns tagged objects. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughAdds a write-only Newtonsoft converter for Unity 6 ChangesTransformHandle serialization
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Hi thanks for the PR. Can you double make sure its NRE and not MRE, MissingReferenceException? Ive repro the other term rather than NRE. Just want to make sure the comments are written clearly and we also handle both cases. |
Why
GameObjectSerializerreflects over component properties and hands the values to Json.NET. On Unity 6, a component property returningUnityEngine.TransformHandlemakes the serializer enumerate the handle's direct children (TransformHandle.DirectChildrenEnumerator). Two problems fall out of that:NullReferenceExceptionfromTransformHandle.AssertHandleIsValidthe moment the underlying object is destroyed. Reading thegameobject/{id}/componentsresource while a game scriptDestroy()s objects (a spawner destroying and respawning pickups makes it reliable) logs the[GameObjectSerializer] Unexpected error serializing value of type UnityEngine.TransformHandlewarning on every read that races a destroy.What
A write-only
TransformHandleConverterthat emitsnullfor the type. It matches by full type name (UnityEngine.TransformHandle) so the package still compiles on every supported Unity version (floor 2021.3, where the type does not exist) without version defines, per theUnity*Compatguidance in CONTRIBUTING. It isinternalfor the same third-party converter-scanner reason asUnityEngineObjectConverter(#1138), and registered inGameObjectSerializer's output settings.EditMode tests resolve the type by reflection and self-ignore on Unity versions without it; the key regression test obtains a handle, destroys its object, and asserts serialization no longer throws.
Observed in the field on Unity 6000.4.10f1 while polling component resources during play mode.
🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
TransformHandlevalues.nullin serialized output.Tests
TransformHandlescenarios.