Giter Site home page Giter Site logo

unity.transformsetterinterceptor's Introduction

What is changing the tranform (position / rotation / scale)?

When working with Unity you've probably asked that question when a transform position/rotation/scale is changing and you have no idea why.

Generally you'd set a breakpoint and debug it this way but for transform you cannot easily do that. The best way seem to be replacing all calls that modify it directly, eg transform.postion = newPosition to some interceptor code that you can control, like Interceptor.SetPosition(transfrom, newPosition)

Unfortunately this is not always possible or easy.

There's now a simpler to use tool that'll allow you to add events to Unity dlls. With that it's possible to write event driven code, eg transform.SetPositionExecuting += (sender, e) => <your handler code> https://github.com/handzlikchris/Unity.MissingUnityEvents

This tool will help you do exactly that but automatically and without modifying any of your source code. Transform Setter Interceptor Workflow

Making This Tool Better - Visual Transform Changes Debugger

I've went further with this concept and created a tool that focuses on tracking ANY changes made to ANY transforms which is then neatly laid out in friendly GUI. Check it out at: https://immersiveVRTools.com/projects/transform-changes-debugger

Visual Transform Changes Debugger features showcase video

Approach

The tool will use IL Weaving and will redirect all the set calls to transform.position, transform.rotation and transform.scale to TransformSetterCallInterceptor where you could add any actions needed.

eg. Method signature and default implementation:

public static void InterceptSetPosition(Transform originalTransform, Vector3 setTo, Object callingObject, string callingMethodName)
    {
        //do whatever you want to do
        originalTransform.position = setTo;
    }

Method will give you access to

  • original transform
  • value that it'd be set to
  • object that does that
  • and calling method name

Setup

You can clone this repository and run it in Unity as an example.

To import into your project:

  1. In Unity add a package dependency to Malimbe which will hook up to Unity build process so the weaver code can work on your assemblies after Unity is done compiling them.

You can do that via manifest.json file located in /Packages folder. You'll have to add following entries (as per Malimbe page)

  
  "scopedRegistries": [
    {
      "name": "npmjs",
      "url": "https://registry.npmjs.org/",
      "scopes": [
        "io.extendreality"
      ]
    }
  ],
  "dependencies": {
    "io.extendreality.malimbe": "9.6.5",
    ...
  }
}
  1. Download and import TransformSetterInterceptor
  2. Recompile
  • If you see an error 'A configuration lists 'TransformSetterCallRedirector' but the assembly file wasn't found in the search paths' That means TransformSetterCallRedirector.Fody is not compiled, you can go to ModuleWeaver.cs and make some non-relevant change (like adding a space) followed by saving to make sure DLL is actually compiled
  1. Now changes to your scripts will trigger recompile which will in turn trigger IL Weaving to intercept your calls

Filtering to specific transform

There's a simple script TransformSetterInterceptorFilter that'll allow you to further narrow down to exact transform that you're interested in via simple drag and drop. From there it'll be very easy to trace what's happening via logging, stack-trace or whatever custom approach you adopt.

Runtime Performance

At build time calls to transform setters will be intercepted and directed to static interceptor class, that should not have significant impact on performance as it's simply adding static method call.

For fallback weaving IL instructions are added at every place that is redirected and Debug.Log will be called for all of them, this call actually gets StackTrace which is rather quite costly. You can stop fallback weaving by removing FallbackSampleNameFormat from configuration.

At later stage I'll look into weaving additional 'if' statements so it can check if change should be printed.

Configuring Interception

In the package, you'll find TransformSetterCallInterceptor.cs with intercept methods. You can adjust that as needed. There's also an assembly attribute specified TransformSetterCallRedirector where you can configure some more options.

  • eventInterceptorTypeName - if different than TransformSetterCallInterceptor
  • replaceCallsFromNamespacesRegex - it'll narrow down types to be looked at when searching for set transform calls
  • ExcludeFullMethodNameRegex - full method name (including) type regex to be excluded. eg. MyType.+::MyMehtod

Using asmdef / Fallback Interception

Separate assemblies will not have access to that TransformSetterCallInterceptor when that happens interception will still be performed but using IL as defined in ModuleWeaver - it'll use Debug.Log with

  • target transform that's being changed
  • object that sets it
  • value

Then you can further narrow it down from log console window and find exactly what you're after.

This is helpful if you like to weave external packages that you don't control (and don't wish to embed) - if you have control over assembly you can copy TransformSetterCallInterceptor.cs class with assembly attribute there.

Configuring fallback interception

You can control few parameters of fallback IL weaving, it's done via XML attributes in FodyWeavers.xml

  • FallbackSampleNameFormat - will control how you see entries in console, there are 3 tokens that can be used and refer to object that invokes the event:
    • {0} - target transform that's being changed
    • {1} - object that sets it
    • {2} - value
  • FallbackReplaceCallsFromNamespacesRegex - it'll narrow down types to be looked at when searching for set transform calls
  • FallbackExcludeFullMethodNameRegex - full method name (including) type regex to be excluded. eg. MyType.+::MyMehtod

Configuring Malimbe

You can further configure Malimbe via FodyWeavers.xml file, you'll find the details in their repository.

Known issues

  • Right now tool works just for direct property setters - it doesn't work with .Set methods (although it'd be rather straight forward to add)
  • You may see some errors that weaving assembly is not available when starting Unity, this is to do with compilation order and should not cause you issues, it'll be gone on next compilation. I've included weaver as source code with asmdef so it's easier to modify weaver. Ideally compiled DLL should just be included
  • There are some DLLs included with the package and also included in Malimbe package, it's not easy to get them referenced without embedding Malimbe package. It shouldn't give you troubles but if something funny happens it'd be worth to look if that's not the cause.

unity.transformsetterinterceptor's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

unity.transformsetterinterceptor's Issues

Filter not working

I drag and drop the transform that I want to pay attention to into an empty gameobject with the filter, but I'm still seeing the calls for all transforms in the scene, am I missing a step?

No observable interception

Following the setup instructions has not resulted in any logging or filterable calls to transform modifications:

On Unity 2019.4.0f1
I observed the 'A configuration lists 'TransformSetterCallRedirector' but the assembly file wasn't found in the search paths' error, to be somewhat confident that Malimbe was running at all. I modified the ModuleWeaver.cs to inspire a recompile, and the error went away, again as prescribed.

I pressed play on my scene, and observed changes to my object under inspection's transform.

No new log messages were observed at this point.

I created an empty game object at the root with the TransformSetterInterceptorFilter.cs script, assigning the object transform that I wanted filtered.

Again, no new messages were observed.

I attached via VS to the Unity debugger port, setting a breakpoint on LogIfMatchesFilter. This breakpoint was not encountered, and the IDE indicated that no symbols were available for the TransformSetterCallInterceptor.cs unit script from the package import. Likewise, no joy with attaching directly to the unity process and setting a breakpoint.

Is there any proper way to observe whether the interceptor is properly woven into the products used in play mode? Am I doing this incorrectly? Are there better debugging steps you would recommend?

Looping compilation?

After importing the package I've been
compiling scripts -> writing package items -> importing scripts -> repeat
for 22 minutes now.
I'm hoping it's going through my assemblies one by one, and will finish soon, but it's getting ridiculous.
2018.4.23

Burst and Mono.Cecil conflicts

I'm using URP, which has Burst as a dependency, and it's causing several compile conflicts with Mono.Cecil, for types like MethodBody, Instruction, OpCodes, MethodReference, CustomAttribute, PropertyDefinition, TypeDefinition and ParameterDefinition etc.

As an example, here is a compile error: The type 'MethodBody' exists in both 'Mono.Cecil, Version=0.10.0.0, Culture=neutral, PublicKeyToken=1ca091877d12ca03' and 'Unity.Burst.Cecil, Version=0.10.0.0, Culture=neutral, PublicKeyToken=fc15b93552389f74'

I've tried adding things like using MethodBody = Mono.Cecil.Cil.MethodBody; but it hasn't removed the compile errors.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.