[Released] Transform Changes Debugger

Actually it was Ultimate Editor Enchancer that had harmony. I’ll check that to see if it’s not unpatching assemblies by any chance.

Loading bar is good but it may not indicate that the method you’re after was patched.

It’s patching all of them in selected assemblies

Yes I am using .Net framework, see screen capture.

I did some more testing:

I have a test cube in my loading scene with a simple move script on it. The move script is disabled. I trigger the loading of the second scene which will trigger the Opsive UCC assembly to load, this has code that will move the cube in the loading scene. The cube starts moving, but the debugger does not register any movements on the cube.

I then enable the simple move script on the cube. The debugger starts to register the movements. The debugger was showing some info above, I can’t recall the exact wording, but it was advising that there were changes to the transform occurring that were not tracked.

Is it possible, that your code does not recognize if an assembly is loaded after the first scene completes loading, and cannot detect the C# code in these late loaded assemblies?

EDIT: I moved the simple move script into the Opsive UCC assembly. Now the debugger won’t track movements on the move script. I definitely have the DLL selected on the main debugger window. It seems that for some reason on my System the debugger will only track code outside of an assembly?

Yes - that would make sense. If assembly is not loaded it’ll not be patched

Can you see that DLL in assembly picker before entering playmode?

If it’s only visible after you enter playmode then - you just need to tick it at runtime. It starts patching process for clicked one.

Let me know if that the case. There’ll be APIs that you can call to quickly automate that click if needed

I can see and select the assembly before going into playmode. Here is a screen shot of the assembly setup.

I created a new assembly with just the simple move script and had this enabled in my loading scene. the debugger still couldn’t track the movements. I next deleted the assembly definition so that the move script was not in assembly, the debugger could now track the movements!! It seems like the debugger cannot track code that is an assembly on my system.

Also, just regarding your comment about the Ultimate Editor Enhancer might be unloading assemblies. I am still testing in a copy of my project, from which I deleted the Ultimate Editor Enhancer and Odin.

Alright, thanks that helps narrow it down as it’s unlikely to be related to other asset.

I’ve checked similar setup with asmdef on my end just now and it looks ok.

I think it’s best to dig into a quick debugging session to find what’s happening.

I appreciate you taking the time to look into this one and also I’m aware that’s not the point of buying asset - very happy to process a refund for you if you’d prefer that.

If you want to go further I’ve put a recording with some steps to help narrow the issue down:

The methods I’m referring to in vid:
TransformChangesDebugger.API.Patches.TransformPatches.InterceptMethodsToEnableChangeTracking
TransformChangesDebugger.API.Patches.CoreInterceptionPatch.SendMessagePrefix

Happy to jump on a quick call if that’s quicker.

I found it. It is throwing an IL compile error in this bit of code. My apologies, the debugger was throwing an error, I just missed it because my own code was throwing lots of errors because the copy project wasn’t setup correctly and so I didn’t look closely.

                        foreach (var methodInterceptorParam in methodInterceptionParamsForSingleAssy)
                        {
                            try
                            {
                                var timeTakenToPatchMethodsSingleMethodSw = new Stopwatch();
                                timeTakenToPatchMethodsSingleMethodSw.Start();

                                var interceptCallParamsForType = TranspiledMethodDefinitions.InterceptionTypeToInterceptCallParameters[methodInterceptorParam.PatchingDueToInterceptedMethodCallFullName];
                                //PERF: patching can take a while, especially for bigger assy like UnityEngine.Core - how to get that speed up?
                                harmony.Patch(methodInterceptorParam.MethodDefinition.ResolveReflection(), transpiler: interceptCallParamsForType.Transpiler);

                                perMethodPatchingDurations.Add(methodInterceptorParam, timeTakenToPatchMethodsSingleMethodSw.ElapsedMilliseconds);
                            }
                            catch (Exception e)
                            {
                                Debug.LogError($"Method Error: {e.Message}");
                            }
                        }
System.NullReferenceException: Object reference not set to an instance of an object
  at TransformChangesDebugger.Editor.TransformChangesDebuggerInitializer+<>c.<.cctor>b__0_9 (System.Object sender, TransformChangesDebugger.API.Patches.RedirectSetterMethodsFromCallingCodeResult result) [0x00001] in D:\UnityProjects\DeadFearRot\DeadFear3\Assets\TransformChangesDebugger\Editor\TransformChangesDebuggerInitializer.cs:90
  at (wrapper delegate-invoke) System.EventHandler`1[TransformChangesDebugger.API.Patches.RedirectSetterMethodsFromCallingCodeResult].invoke_void_object_TEventArgs(object,TransformChangesDebugger.API.Patches.RedirectSetterMethodsFromCallingCodeResult)
  at TransformChangesDebugger.API.Patches.TransformPatches.InterceptMethodsToEnableChangeTracking (HarmonyLib.Harmony harmony, System.Collections.Generic.List`1[T] assemblyPaths) [0x00369] in D:\UnityProjects\DeadFearRot\DeadFear3\Assets\TransformChangesDebugger\API\Runtime\Patches\TransformPatches.cs:147
  at TransformChangesDebugger.API.TransformChangesDebuggerManager.Initialize (System.Collections.Generic.List`1[T] allAvailableAssyPaths, System.Collections.Generic.List`1[T] assemblyPathsChosenToPatchByUser) [0x00080] in D:\UnityProjects\DeadFearRot\DeadFear3\Assets\TransformChangesDebugger\API\Runtime\TransformChangesDebuggerManager.cs:99
  at TransformChangesDebugger.Editor.TransformChangesDebuggerInitializer..cctor () [0x001a2] in D:\UnityProjects\DeadFearRot\DeadFear3\Assets\TransformChangesDebugger\Editor\TransformChangesDebuggerInitializer.cs:95
UnityEditor.EditorAssemblies:ProcessInitializeOnLoadAttributes (System.Type[])

Here is the method that generated the error:

#if UNITY_EDITOR
        /// <summary>
        /// Function used to create a new controller volume
        /// </summary>
        [MenuItem(m_createVolumeMenuItem)]
        public static void CreateInteriorWeatherControllerVolume()
        {
            GameObject newVolumeObject = new GameObject("New Gaia Interior Weather Volume")
            {
                transform =
                {
                    position = SceneView.lastActiveSceneView.camera.transform.position
                }
            };

            InteriorWeatherController interiorController = newVolumeObject.AddComponent<InteriorWeatherController>();
            interiorController.Setup();

            BoxCollider boxCollider = newVolumeObject.AddComponent<BoxCollider>();
            boxCollider.size = new Vector3(30f, 30f, 30f);
            boxCollider.isTrigger = true;

            Selection.activeObject = newVolumeObject;
            EditorGUIUtility.PingObject(newVolumeObject);
            SceneView.lastActiveSceneView.FrameSelected();
        }
#endif

@Zaddo thanks - I can recreate the issue now.

It’s down to a code pattern that tool rewriting can’t handle (assigning value via property initializer) - I’ve raised a bug for that and will sort it out later. But that may not be quick.

In the meantime I’ve added better error handling for patching. Really for patches that fail it should just continue with others rather than fail completely.

You can find the change here:
https://github.com/handzlikchris/Unity.TransformChangesDebugger.API/commit/89e10e141c794e567ab3dde9e42df40d67ac263e

Once you apply it your changes should start showing.

1 Like

@ChrisHandzlik Very nice assets! Is it compatible with Apple Silicon Mac? I followed the steps below and it didn’t work. When I searched the Harmony Issue Tracker, I found Patch failure on macOS with Apple Silicon chip & Unity 2021.2 arm version · Issue #424 · pardeike/Harmony · GitHub.

  • Imported the asset.
  • Followed the instructions to approve the use of the .NET Framework.
  • Opened the “Hard to pinpoint jitter” demo from “Quick Start”.
  • Pressed “Play” (from here, I have recorded in the attached video).
  • Selected “TrackedObject-1” and chose “Open Visual Transform…”.
  • A window appears, but no objects are displayed in the “Tracked Objects” section.
  • The Console displays an error “Win32Exception: Invalid data”, and the word “Harmony” appears in the middle of the stack trace.

I would appreciate any advice.

Stack Trace

Win32Exception: Invalid data
MonoMod.RuntimeDetour.Platforms.DetourNativeLibcPlatform.SetMemPerms (System.IntPtr start, System.UInt64 len, MonoMod.RuntimeDetour.Platforms.DetourNativeLibcPlatform+MmapProts prot) (at <88b084d277f344aa9c2904c640976875>:0)
MonoMod.RuntimeDetour.Platforms.DetourNativeLibcPlatform.MakeWritable (System.IntPtr src, System.UInt32 size) (at <88b084d277f344aa9c2904c640976875>:0)
MonoMod.RuntimeDetour.DetourHelper.MakeWritable (MonoMod.RuntimeDetour.IDetourNativePlatform plat, MonoMod.RuntimeDetour.NativeDetourData detour) (at <88b084d277f344aa9c2904c640976875>:0)
MonoMod.RuntimeDetour.Platforms.DetourRuntimeILPlatform._HookSelftest (System.Reflection.MethodInfo from, System.Reflection.MethodInfo to) (at <88b084d277f344aa9c2904c640976875>:0)
MonoMod.RuntimeDetour.Platforms.DetourRuntimeILPlatform..ctor () (at <88b084d277f344aa9c2904c640976875>:0)
MonoMod.RuntimeDetour.Platforms.DetourRuntimeMonoPlatform..ctor () (at <88b084d277f344aa9c2904c640976875>:0)
MonoMod.RuntimeDetour.DetourHelper.get_Runtime () (at <88b084d277f344aa9c2904c640976875>:0)
MonoMod.RuntimeDetour.DetourHelper.Pin[T] (T method) (at <88b084d277f344aa9c2904c640976875>:0)
HarmonyLib.MethodPatcher.CreateReplacement (System.Collections.Generic.Dictionary`2[System.Int32,HarmonyLib.CodeInstruction]& finalInstructions) (at <88b084d277f344aa9c2904c640976875>:0)
HarmonyLib.PatchFunctions.UpdateWrapper (System.Reflection.MethodBase original, HarmonyLib.PatchInfo patchInfo) (at <88b084d277f344aa9c2904c640976875>:0)
HarmonyLib.PatchProcessor.Patch () (at <88b084d277f344aa9c2904c640976875>:0)
HarmonyLib.Harmony.Patch (System.Reflection.MethodBase original, HarmonyLib.HarmonyMethod prefix, HarmonyLib.HarmonyMethod postfix, HarmonyLib.HarmonyMethod transpiler, HarmonyLib.HarmonyMethod finalizer) (at <88b084d277f344aa9c2904c640976875>:0)
TransformChangesDebugger.API.Patches.CoreInterceptionPatch.PatchSendMessage (HarmonyLib.Harmony harmony) (at Assets/TransformChangesDebugger/API/Runtime/Patches/CoreInterceptionPatch.cs:27)
TransformChangesDebugger.API.TransformChangesDebuggerManager.Initialize (System.Collections.Generic.List`1[T] allAvailableAssyPaths, System.Collections.Generic.List`1[T] assemblyPathsChosenToPatchByUser) (at Assets/TransformChangesDebugger/API/Runtime/TransformChangesDebuggerManager.cs:97)
TransformChangesDebugger.Editor.TransformChangesDebuggerInitializer..cctor () (at Assets/TransformChangesDebugger/Editor/TransformChangesDebuggerInitializer.cs:95)
Rethrow as TypeInitializationException: The type initializer for 'TransformChangesDebugger.Editor.TransformChangesDebuggerInitializer' threw an exception.
TransformChangesDebugger.Editor.TransformChangesDebuggerInitializer+<>c.<.cctor>b__0_0 (System.Object sender, System.EventArgs args) (at Assets/TransformChangesDebugger/Editor/TransformChangesDebuggerInitializer.cs:40)
System.AppDomain.DoDomainUnload () (at <16d1a1e3fafa4d23a275526c945e1b62>:0)

Hi @anoworl - thanks! You’re right it doesn’t support Apple Silicon yet. And the harmony issue you’ve found is at the core of it.

It looks like needed change was merged to Harmony in June but I’ve not yet had a chance to update.

I’m not quite sure where that’d happen, if Mac is your only use I’d be happy to get it refunded for you.

Also till it’s updated you may find MissingUnityEvents to be helpful. It’s not as polished but it achieves very similar goal using slightly different approach that should work on mac

[SOLVED] The issue is that we are creating our unit prefabs at runtime, so adding the tracker to another static component allowed me to then track the one I wanted. Might want to give a hint about attaching the component to an object in the scene before runtime in the debugger window itself when nothing is matching…

Hey @ChrisHandzlik I have been trying to debug an issue with one of our units rotation constantly being set to the wrong direction. I was excited when I found your asset, but I have been unable to get it to work. I think I set everything up as you advise and the example scenes do work.

Here is a video showing me spawning the unit, confirming it has the Tracker component, even tried re-dragging the unit into the Tracker Debugger which it allows, but it doesn’t show anything. I have enabled ALL scriptassemblies and yet I’m not getting any info on position or rotation updates.

You can see me manually set the rotation Y to 0 in the inspector about halfway through the video and it immediately gets changed back and yet nothing shows in the debugger window… What am I missing?

We are also using Odin very lightly in some places in our project (I mention this since I see many posts in this thread about issues with it), but I’m not seeing any errors…

Cool - glad you found it! Your game looks great.

Btw. chaning through editor doesn’t go via properties / methods on c# side and might not show.
All the changes that go via managed side, like your scripts / 3rd party scripts will show.

Hi there, could you layout your workaround here ? We’re in the same context with dynamically spawned units. Thanks !

I had a quick go today but I wasn’t able to identify the cause of an unexpected transform change, yet.
I expect the change is occurring somewhere in an assembly I haven’t found yet.

It was hard to tell if the tool was even working, since nothing appeared in the window. Perhaps there could be some help, for example if there is any TrackChanges components in the scene they appear in the window, with a warning if there are no tracked movements yet.

Also it is hard to figure out what assemblies to try enable, perhaps the tool could look at the gameobject with the TrackChanges component, look at the all the scripts on it, and figure out what their assemblies are and offer to enable them.

I’m using XRI which moves a rigidbody on the gameobject, so it’s possible my issue is physics movement, but it’s hard to tell, it would be nice if that was supported.

Does this tool support animation changes too?

Hard to find transform changes is a known challenge with Unity so we try write our code to avoid this happening. So it’s quite unlikely that it’s our code that’s the problem.

I look forward to figuring this out and using this tool in the future!
Thanks

I used the other tool linked by chris “MissingUniyEvents” and managed to get callbacks on native field changes. GitHub - handzlikchris/Unity.MissingUnityEvents: Editor extension to generate events that are executed before property set, eg. Transform-position, Transform-rotation, Transform-parent which allows to write more event driven code or debug property changes that are not simple to track down. Easily customisable to allow adding events to different property setters / types.

I just bought the tool, installed it and tried to track position changes for an object which is spawned at runtime into the scene.

I have ticked all the needed assembly boxes and restart Unity, as it threw errors at me after the assemblies had changed.

I connected the TrackTransformChanges Script to my prefabs I wanted to track and attached a function to the PositionChanged event.

I made Debug.Log into the areas were the position is changed. The tool did track nothing at all.
I have no idea what I should do to make this work. I have read the documentation, restarted Unity several times with no avail.

Any help would be greatly appreciated otherwise I need to refund.

Thanks for getting in touch.

I’ve sent you a PM with slightly modified version that’ll correctly track instances created at runtime.

You will be able to enable it in settings.

Also added example scene showing that at work (DynamicallyCreatedObjects.unity)

Let me know how you got on.

1 Like

Thanks, that was fast. Much appreciated! I adjusted my review accordingly.

1 Like

Hi - I’ve just purchased the asset, and would like this feature too. The transform I’m trying to track belongs to a prefab that’s instantiated at runtime. Could this be sent to me? Or perhaps included in an update to the package? Thanks!

EDIT: Even adding a TrackTransformChanges object to a static object at the root of my boot scene (which hangs around forever) doesn’t appear in the visual debugger. This is with ALL assemblies patched too. Perhaps a Unity 6.3 issue?