Flicker at the end of rotate 90° with animations

Hi guys,

I want my 3D game characters to move on a grid. Characters must turn 90 degrees left or right remaining at the same position. I use mixamo’s animations : “turn right 90” and others alike.

When a turn starts, I trigger the animation (and lock the character with a boolean to prevent multiple actions)

if (Input.GetKey(KeyCode.LeftArrow))
{
        isLocked = true;
        GetComponent<Animator>().SetTrigger("left-turn");
}

Note: The animation makes the visual of the character turning, but the transform is unchanged.

Then at the last frame of the ‘left-turn’ animation, an event rotates the transform and unlocks the character.

public void EndOfLeftTurn()
{
       transform.rotation = Quaternion.Euler(0, transform.rotation.eulerAngles.y - 90f, 0f);
       isLocked = false;
}

Note: The rotation of the transform is to actually set the character in the proper orientation resulting from the rotation and to have the proper orientation to play the next animation.

Finaly an animation transition brings the character to its ‘idle’ animation.

It globally works as expected. The problem is that during a very brief moment (flicker) the character appears with an additional 90° rotation.

My guess is : after the transform.rotate = … is performed by the event, the last frame of the animation lasts again for a few milliseconds. Here is my understanding of the steps. T shows the orientation of the transform, A shows the visual of the animation.
175648-rotation-problem.png

I’m stuck for a couple of days now and what bothers me is that I have no clue to solve this issue.

If my understanding is right, is there a way to enforce the transform.rotation = … to be exactly executed after the last frame of the left-turn animation and before the first frame of the idle animation ?

Or is there another way to achieve this transition correctly ?

Thanks for your help.

I am not sure this will solve your problem but have you can have more control of update order by having different updates in your loop like:

void Update()
{
    EarlyUpdate();
    LateUpdate();
   // VeryLateUpdate() etc...
}

void EarlyUpdate()
{
// do things early in the update
}

void LateUpdate()
{
// do things late in the update
}

The only thing is that it will all happen on the same frame. If you really need to do things per frame, you should use Coroutines and while loops. Hopes it helps!

Hi @LoloBad, if you coordinate your logic with WaitForEndOfFrame I believe you can achieve what you want to.

I tried but I’m not sure I’m using WaitForEndOfFrame() well.

I modified my EndOfLeftTurn() method this way :

public void EndOfLeftTurn()
{
       StartCoroutine(WaitForEndOfAnimation());
}

public IEnumerator WaitForEndOfAnimation ()
{
       yield return new WaitForEndOfFrame();
       transform.rotation = Quaternion.Euler(0, transform.rotation.eulerAngles.y - 90f, 0f);
       isLocked = false;
}

All this has no effect. I still have my flicker at the end of my turning animation.