I’m having trouble getting my custom animation system working properly with ‘Animate Physics’ turned on in the Animator Component.
I use a completely custom playable graph which requires switching clip playables in and out constantly to achieve ‘Motion Matching’. It works fine in other modes but in ‘AnimatePhysics’ the animation flickers continuously and the motion is all screwed up. The flicker seems to occur only when I disconnect a playable or connect a new one (which can happen very often in motion matching).
My understanding is that ‘Animate Physics’ causes the animation to be processed in step with the physics update (FixedUpdate). With that in mind I’ve tried the following things but none have worked:
Updating my animation system in FixedUpdate instead of Update when AnimatePhysics is on
Setting the playable graph update mode to ‘DirectorUpdateMode.Manual’ and manually evaluating the graph in the fixed update.
I’d really appreciate it if anyone has any insight.
Take a look at the way they set up the graph in the Simple Animation system. Basically, they use a PlayableBehaviour class as the root of the graph with the MixerPlayable connected to it and they do all graph modifications in its PrepareFrame method which gets called as part of the graph update at whatever rate you’re using.
That’s how I set it up in Animancer and I haven’t had any issues like what you’re describing.
Ok so I modified my system to go through a custom playable behaviour. All the logic for the graph is being modified in the PrepareFrame callback and I’m using the deltaTime from the FrameData argument for all that logic.
It’s a little less jittery than before but my problem still persists for the most part with Animate Physics. Here is a video showing what I mean. The first part shows it behaving normally, the second half is when I turned on Animate Physics. It’s reverting to the bind pose for a frame every time the playable graph structure is modified.
I’m ultra stumped… I must be missing something somewhere. If anyone has any insight it would be greatly appreciated. Do I need to change the DirectorUpdateMode for the playable graph maybe?
That’s really odd, but I can think of a few things to try:
Make sure it happens when you start in Animate Physics mode too. There are some bugs with changing modes mid game in earlier Unity versions and I don’t know if 2018.4 fixed them.
Make sure you have the DirectorUpdateMode set to GameTime when you create the graph. For some reason the default is DSPClock which has something to do with audio.
Maybe try adding an extra clip to the mixer at super low weight (but not 0). Alternate between disconnecting and reconnecting it repeatedly to see if it causes constant flickering. If it does then this is definitely a Unity bug.
Try a different Unity version. I’ve described the issues I’m aware of with various versions here.
I have tested it numerous times starting in either mode without switching at run-time.
DirectorUpdateMode is set to GameTime
I created a test project to try isolate this issue. Turns out its easy to repo, see below
Tried 2018.4, 2019.1, 2019.2 all have the exact same issue.
So here is my little test project I threw together. I tried to make it as simple as possible to isolate the problem. Basically, the animation starts with one clip in a mixer and then adds an additional clip every 1 second, blending them equally. Couldn’t think of a more simple test.
Turns out that with ‘AnimatePhysics on,’ simply creating and adding a clip playable to a mixer causes the character to go into bind pose for a single frame. This occurs whether the new clip has a weight of 0 or not and only with ‘Animate Physics’. See the video below.
At this point I’m thinking this is a bug in Unity. However, if anyone would be willing to look at the test package and see if there is something blatantly obvious that I’m doing wrong to cause this problem, I’d really appreciate that. Here’s a link to the test package: https://drive.google.com/open?id=1VYuVPhHpPTnYfEwqsD-QhRieXjQ7hozb
I just tried it in 2018.1 and didn’t see any issue.
But m_mixer.DisconnectInput(i); doesn’t exist in this version so I had to replace it with m_testAnimationComponent.Graph.Disconnect(m_mixer, i);.
So it’s possible a new bug was added after 2018.1, but I’m thinking the new mixer.DisconnectInput method has a bug even though it sounds like it should do the exact same thing.
See if that helps, but either way you should probably report a bug.
Turns out I was wrong, it doesn’t work in 2018.1. The prefab was broken so I had to drag in a new copy of the model and copy over the component but evidently forgot to set it to animate physics mode.
But I found a solution: replace your playable output with AnimationPlayableUtilities.Play(m_testAnimationComponent.GetComponent(), m_target, m_testAnimationComponent.Graph);
Taking a look at that method in IL Spy, it creates a playable output like you are, but it also calls graph.SyncUpdateAndTimeMode(animator); which is an internal method that calls into C++ so I have no idea what it actually does, but it sounds like exactly the sort of thing that could cause this issue.
So this behaviour may actually be reasonable when whatever that method does isn’t done and the bug could simply be the fact that it’s internal.
Actually, that might also solve the issue I was having in Animancer where changing the update mode after startup had no effect. It might just need me to use reflection to call that method when the mode changes.
@Kybernetik Man, I have been trying to solve this issue for 3 weeks now. Trying similar things to what CptKen was doing as workarounds. The flickering is still a problem in 2019.4. Thanks to both of you for raising this thread and to Kybernetic for posting this solution. Much appreciated.
Yeh this one did my head in back then. That function really should be exposed and the documentation does not help with finding this out.
This really aught to be included in the Playables API manual. Unfortunately, I think Playables have been abandoned in their current state while they spend all their time on DOTS animation.