Animation to turn character at 180 degrees dont go full 180 degrees

I thought animating a 180 turn will be a simple task and here we are at the unity forum.
My goal is to play 180 turn animation which will update character’s rotation values as well.

I found this animation on Mixamo and on preview it looks like exactly 180 degrees.

‘Apply root motion’ checkbox is enabled on character’s animator

But when I play this animation in my project character’s Y rotation updated from 90 to 265.071.
Is there a way to achieve exactly 180 y rotation during animation configuring animation in unity editor or I need to search for an animation with perfect degrees?

Can you screenshot the root motion settings on the animation clip? Try setting the rotation to “Original” if it’s incorrectly set to “Body Orientation”. (You would typically want all of those settings to be “Original” since most of the time you want the root motion that was animated on the clip, and typically you would bake Y Position most of the time and XZ if the clip isn’t supposed to move their position just to avoid the miniscule drifting that can happen, for example, when looping an idle animation clip over and over again).

These settings are what I’m referring to:


My animation settings look like that if I want the rotation from animation update gameobject’s rotation as well. Right now Im expiriecing strange behaviour that each animation ends with different Y rotation, start value is 90, but after animation it become 235.5 236.2 and etc. This is really weird. I also dont see any effect from checking ‘Root transform position Y/XZ’, after animation finishes there are small changes(0.02-0.08 at character’s X and Z coordinates)

I found the way to achieve desired behaviour by disabling ‘Apply root motion’ at animator, and turning character myself by coroutine during animation.

It looks smth like that:

    IEnumerator MoveAtDirectionToDistance(Vector2 direction, float distance, float speed, bool makeTurn = false) {
        if (makeTurn) {
            status.Right180Turn();
            float turnTime = 0.8165f;
            float endRotation = direction == Vector2.right ? rightDirectionRotation.y: leftDirectionRotation.y;
            yield return StartCoroutineAndStopCurrent(Rotate(turnTime, endRotation));
        }
        status.Walk();
        yield return StartCoroutineAndStopCurrent(Move(direction.normalized, distance, speed));

        status.Stay();
    }

        IEnumerator Rotate(float duration, float endRotation) {
        float startRotation = transform.eulerAngles.y;
        float t = 0.0f;
        while (t < duration) {
            t += Time.deltaTime;
            float yRotation = Mathf.Lerp(startRotation, endRotation, t / duration) % 360.0f;
            transform.eulerAngles = new Vector3(transform.eulerAngles.x, yRotation, transform.eulerAngles.z);
            yield return null;
        }
    }

    void Update() {
        CheckMovementAnimation(0);
    }
    
    void CheckMovementAnimation(int layer) {
            if (status.isWalk) {
                Play(Animations.WALK, layer, false, false, 0.05f);
            } else if (status.isStay) {
                Play(Animations.IDLE, layer, false, false);
            } else if (status.isRight180Turn) {
                Play(Animations.RIGHT_180_TURN, layer, false, false);
            }
      

This method will update character status to ‘turn’ state, Update method will trigger animation via animator and CrossFade method, and after updating character status first method will run coroutine to rotate gameobjects

This solution doesnt looks good for me, but it makes position and rotation of characters fully expected after animation is played, hope for your advices to achieve same result in better ways :slight_smile:

Does the animation itself actually turn 180 degrees? Is this on a character with a rigidbody with some friction? Were you calling .Play() from script or .Crossfade()? Does the animator state have a transition out of it where it would blend out the animation during part where the turning is still happening thus preventing the full turn animation from playing back?

I dont know and I dont know how to check it. As I mentioned above, in case ‘apply root motion’ enabled, it change object’s rotation at 135-170 degrees, each turn random values in this range. If I check animation at mixamo it looks like full 180. If I check in unity editor it looks like that:



Animation is 30 fps(my game is 60fps) and 49 frames length.
and after playing animation in this window multiple times I get another character position at frame 0, so I dont know can I trust this player

I placed model in an empty object and this object contains animator and character controller, the model have transform as an only component.

Crossfade with 0.2 as normalized transition time, but I can change it for different animations

Not sure I understand that correctly, rotation animations always followed by walking animation called by crossfade with 0.05 as normalized transition time, before rotation there are only 2 possible animations, idle or walking. So I guess like last 5% of turn animation are affected by following walk animation. That means that next after turn animation should always check is turn animation already finished?

Okay, looks like the animation more-or-less is 180 from that playback.

Crossfade .2 means it will transition linearly over first 20% of animation, so if any rotation happens within first 20% of animation, the character will be missing out on part of that. That might be an issue depending on the turning animation itself.

The transition parameters I’m talking about are these:

Transition Duration of .0625 means the last 6.25% of the animation it will be transitioning back to your walk animation. If any turning happens during that last % of the turn animation then it would also be missing out on that.

Does calling .Play() for the state and setting Exit Time to 1 result in a full turn as expected?

If first 20% of current animation are spent to transition from previous animation to current, shouldn’t the 21% percent or even 20.01% of current animation always look the same, and therefore have the same rotation? Especialy if previous animation doesnt change object’s rotation?

Im using the ‘hand made’ animator from here, https://www.youtube.com/watch?v=Db88Bo8sZpA to not play with that arrows from animator) so Im not very familiar with those arrow transitions, is that looks correct?



If yes, character is still rotate to random angle and 3 attempts to trigger rotation from 90 degrees produced next results:
90 ->263.832
90 ->262.613
90 → 264.05

If first 20% of current animation are spent to transition from previous animation to current, shouldn’t the 21% percent or even 20.01% of current animation always look the same

No. The animator is rotating the character every frame based on the deltaRotation of that frame.

is that looks correct?

Yes. Personally, I wouldn’t use that “hand made” animator since it will get out of hand in a different way. The biggest reason animator controllers turn into spaghetti is because the developer isn’t utilizing blendtrees to combine similar states (idle, walk, run, sprint can all be one state) and aniamtor layers (override layers can have one central “empty” state and have one-off actions be states that transition back to the empty state when they’re done in a nice hub-and-spoke setup).

If yes, character is still rotate to random angle and 3 attempts to trigger rotation from 90 degrees produced next results:

These results seem pretty good, honestly. You’re within a couple degrees of a full 180 every time. Probably a result of floating point precision errors when calcing the deltaRotation. In a regular third person action game, these results would be acceptable. However if you’re making some grid based and really need it to match 100% then you should be using something like Target Matching or your coroutine approach (although instead of coroutines I would opt to use a package like DoTween since then you could just do a transform.DORotate(lookDir, .85f); when calling Crossfade() and it will end in the correct rotation.

Thank you for your help! Unfortunately, my game requires 100% rotational accuracy, so I’ll be using a solution with coroutines/DoTween to keep it simple :slight_smile: