Pay attention to amplitude of the yellow hexagon when Animator is enabled/disabled.
The project is in the attachment.
However today I received an email in which it was said that this behaviour is by design:
I can’t express my strong feelings about this issue and this reply. Why on Earth does the Animator rewrite the Transforms which aren’t being animated at that moment? And how to animate GameObjects which contain children being simulated by Physics?
Here is how it looks in game prototype. Pay attention on the behavior of the pom-poms on the girl’s hat:
This has always worked this way, and it’s always been a horrible design decision.
It means that you run into issues like the one you’re talking about, where not animating a thing doesn’t mean that it animates. It complicates matters a lot.
It also means that animations are not independent. If you add things to one animation, that’ll change what a different animation moves.
There’s also (of course) no documentation about where the position of the transform that doesn’t have any motions in the current motion comes from.
This should definitely be an option on the animator (“animate transforms with no curves”), and should definitely be off by default.
That your point of view, but we made this decision for a good reason.
The old legacy animation system only write properties that are animated for the current state, if you do a cross fade between a clip that animate A.color and another one that doesn’t, the property A.color won’t be blended and will keep the same value, so far so good, now if you crossfade into another clip that animate A.color it could create a discontinuity in the animation. When you start to add more and more clip you end up with a system that is not deterministic, depending on the order on which you play the clip you get different result.
We had a lot of bug report which end up to be non deterministic behaviour because of this.The feedback from our user at this time was please make a deterministic animation system.
So we made the animator component and implemented the write default values. The default values are setuped by the animator when it get activated, basically it does read all the animated property from the scene are store them internally, so when you blend two clip togheter if one of them doesn’t have an animated values for a particular properties it simply use the default values to fade in and out, you can change this behaviour per state if needed to keep the value from the previous state but still all properties are always written every frame.
You get a lot of bug reports about this too–it fixes one set of problems but introduces another. There are still improvements that can be made.
It would help to have an AvatarMask on the Animator itself, which tells the animator to leave certain objects alone entirely. The problem (as I’m sure you know) is that joints in assets meant to be controlled by physics end up getting taken over by Animator, because since they’re in the base asset they end up getting baked to animations as well, which is hard to prevent in many baking/animation export workflows.
(That said, AvatarMasks are very awkward to work with: if you add a joint to an asset, separate AvatarMasks won’t update automatically, and if you update them from the source, it loses the entire mask set and you have to create it all over again. I suspect I’ll end up writing my own tool to generate them to make them more maintainable, so I can just list “include only these objects” or “include all objects except these” and auto-generate all masks like that.)
I wonder if it’s possible to work around this in script by recording an object’s transform before Animator runs and then restoring it after. I’m guessing it’s possible if the animator is in regular mode, but it might be trickier in animate physics–not sure if there are callbacks in the physics loop where they’d be needed.
Here’s a script that tries to work around this like I described above. It stores transforms before Animator runs, and then restores them afterwards. If I put this on an Animator who is clobbering an object’s rigidbody motion, and add the object to the transforms list, the rigidbody starts working again.
It won’t work if the animator is in update physics. See: Unity - Manual: Order of execution for event functions. The Animator update order in physics mode isn’t described there, but it happens inside the “Internal physics update” block, and we’d need a callback inside that block which happens after Animator but before physics. Maybe there’s a hack with Playables that could do this, but I haven’t found one.
using System.Collections.Generic;
using UnityEngine;
public class MuteAnimatorForTransforms: MonoBehaviour
{
public Transform[] transforms;
struct SavedTransform
{
public Transform transform;
public Vector3 localPosition;
public Quaternion localRotation;
public Vector3 localScale;
};
List<SavedTransform> savedTransforms = new List<SavedTransform>();
void SaveTransforms()
{
savedTransforms.Clear();
foreach(Transform t in transforms)
{
SavedTransform savedTransform;
savedTransform.transform = t;
savedTransform.localPosition = t.localPosition;
savedTransform.localRotation = t.localRotation;
savedTransform.localScale = t.localScale;
savedTransforms.Add(savedTransform);
}
}
void RestoreTransforms()
{
foreach(SavedTransform savedTransform in savedTransforms)
{
savedTransform.transform.localPosition = savedTransform.localPosition;
savedTransform.transform.localRotation = savedTransform.localRotation;
savedTransform.transform.localScale = savedTransform.localScale;
}
}
void Update()
{
SaveTransforms();
}
// Animator happens between these two calls. https://docs.unity3d.com/Manual/ExecutionOrder.html
void LateUpdate()
{
RestoreTransforms();
}
}
Ok. I guess I understand the reasons.
However I still have questions.
If I undestand it right, the Animator writes all the properties which are animated by any Clip/State in the AnimatorController. If current Clip/State doesn’t animate the property the Animator will just write the default value of that property which is captured… and here is the question… when does it capture the default value?
As far as I understand, it should capture it every frame. Otherwise we couldn’t move our Transforms via the code if those Transforms are animated by some Clip.
The next question comes out from the first one. Despite the fact that the Animator constantly writes the animated parameters which are not being animated at the moment, we still can alter them from our code (e.g. Transforms). So why Animator interferes with Physics?
See the ExecutionOrder link above. You can modify positions from code, but they’ll be overwritten by Animator at its next update, which is “Internal Animation Update” if you’re in the default animator mode. You can override Animator if you design around that, which is what I’m doing in the above code.
this is exactly what does happen, the only way to overwrite the animator is to modify thoses properties on a LateUpdate, but on the next frame they will get overwritten.
When you setup your animator in AnimatePhysic, the animator start to get ticked on FixedFrame, the root motion stuff need to be evaluated before the physics to move the root rigidbody/character controller and then after the physics we do process the animation pose and write it into transfrom.
Huh, surely animation needs to happen before physics, so animation on kinematic rigidbodies (foot) affects non-kinematic rigidbodies (ball) without being delayed by a frame?
(I use third-party physics because I’ve never found Unity’s built-in physics to be very usable. All of this is too black boxed and out of the developer’s control…)
@Mecanim-Dev thanks for the explanation. It seems it’s a very deep and even philosophical topic but right now I have to solve a specific problem.
In our game we have a girl who has a hat with pom-poms. These pom-poms are physical objects so they realistically jumps when the girl drives over road bumps. However we have to animate those pom-poms when the girl turns her head: more specifically we have to move the joint anchors of pom-poms.
And here comes the mentioned problem: if we animate those pom-poms they stop behaving as we wanted. Note: the gif shows the correct behaviour because the movement of joint anchors is hard-coded. But surely we’d better animate them because it’s much cleaner solution.
So my question is how could we overcome this problem without hard-coding?
You can try to manually update the animation system before the physics step.
1.Disable the animator component, you don’t want to use the builtin update loop because the animation write step happen after the physics.
2. Create a mono bevahiour that will act as the UpdateManager for your animator component, override the FixedUpdate callback and from there call animator.Update(Time.fixedDeltaTime);
By doing this you are completly changing how the animation system is updated and it should be more aligned with what you want to achieve
I’m not sure that Dev’s suggestion would help. It would change the order of updates, but Animator would still be updating the transforms with rigidbodies on them, so it would still prevent physics from working.
My answer was mostly ignored, but as far as I know it’s the closest to a solution: undo the animator’s effects on the transform so it doesn’t interfere with physics. The transforms would still move, since their parent (the head, presumably) would still be animated, but the joints with dynamic effects applied to them wouldn’t.
I don’t know if that would fix it by itself, since I’ve always found that Unity’s builtin physics behave strangely and is hard to work with, but it’s a piece of the puzzle.
Baste’s suggestion is to put the rigidbody transforms outside of the animated skeleton, and have a script that runs in FixedUpdate that moves the transforms (or a kinematic parent) so they follow. That would work too, though it would probably not work in animation/transition previews where the script wouldn’t be running.
Hi, sorry for “ignoring”. I actually did not ignore your answer and I did try your suggestion. But it didn’t help, so I forgot to respond. I can upload a scene which uses your method if you’d like, but I believe you can check it with my original scene by yourself even quicker.
Nobody’s giving you a complete drop-in solution, you need to take the pieces people give you and put it together into a solution yourself.
Your scene has animation on a dynamic object, which will never work and isn’t the right way to influence a dynamic object with animation. Animation is going to put the object in a fixed position and won’t combine with dynamics. You can animate a kinematic object that dynamic objects are attached to, or animate an invisible helper object and read the motion to apply it as force to a dynamic object, or (with some physics systems) animate an invisible non-dynamic copy of an object and use it as a goal for a dynamic object, but you don’t put animation and physics on the same object.
This scene is for demonstration only. If you pay attention you’ll notice that the animation which alters the Transform of dynamic object is not being played; it’s just there in the AnimatorController.
In real case I disable physics simulation right before playing the animation.