Search Unity

Animator Playable Graph Cleanup

Discussion in 'Animation' started by gww2, Oct 15, 2018.

  1. gww2

    gww2

    Joined:
    Jan 13, 2017
    Posts:
    21
    In our game we have generic pooled objects with a basic playable graph created, except for the final hooks into animationclipplayables. I was trying to avoid constantly destroying and recreating the parts of the graph that do not change, but each time we'd connect the new clips the previous clips would hang around on the animator.

    For example if I had a graph that the final mixers connected to 5 clips and I wanted to change it to a new set of 5 clips I would step through my current animationclipplayables and destroy them, then step through the inputs on the mixer that had those clips assigned and disconnect them. Next I would create 5 new animationclipplayables for my new clips and connect them to the mixer.

    Watching the animator component in the editor, the clip count (along with all the other counts) would be doubled (5 to 10 in this example). This would continue to accumulate on each reconfigure as long as the object was still active. It looked like when the object was deactivated and returned to pool these clip counts would eventually clear out. I really do not want to create a cooldown period for objects when they're used from the pools, so for now I'm stuck destroying the entire graph every time I swap configurations. Occasionally we still see the counts doubled, but never more than that.

    Is there any way to force the animator to let go of all these lingering clips?
     
  2. gww2

    gww2

    Joined:
    Jan 13, 2017
    Posts:
    21
    So destroying the playable graph also fails at some of the cleanup. If I destroy a graph and rebuild a new one in the same frame additional rotations/movements are additively combined in the animations.
     
  3. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    Have you reported this as a bug? Sounds like a pretty bad one.
     
  4. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    I found a similar bug while developing Animancer (and reported it). Telling the Animator to play a graph that it's already playing adds all the clips to it again and doesn't clear them. It didn't actually affect the model, but did impact performance when the count got high enough. I was able to work around it by not telling it to play the graph in OnValidate, but I never found a way to actually check if it's playing or clear it or anything.
     
  5. gww2

    gww2

    Joined:
    Jan 13, 2017
    Posts:
    21
    The project is unfortunately too large and complex to include with a bug report. We're in the middle of a release push so I don't have the time to try and create a simpler repro case right now. The situation that seemed to trigger the most consistently was destroying the graph and rebuilding it in the same frame. I am altering the number of transforms after the destroy and before the rebuild. but that wasn't consistently linked to it (also occurred on a block that has the exact same transforms). I do call Animator.Rebind after altering the number of transforms as well. If there is an order issue on how I should be doing this, it would be nice to have it in the documentation anywhere.

    @SilentSin That sounds exactly like the initial bug I saw. Initially I suspected that as also causing the second issue, but now it appears to be separate. In the second case the clip counts and such are correct and cleared up, but additional positioning and rotating is done on the bones during the animation.

    My current workaround is to disable the gameobject for a frame when I detect that I'm trying to update the graph in the same frame it was created. This appears to work, but is a pretty janky solution.

    It would be really convenient if there was a clear function to call on an Animator to clear all these lingering references, since I don't seem to have any control on them.