How to smoothly switch from script controlled rotation to animator controlled rotation (and the other way around)

I’m rotating the head of my animated character by script using Animator.SetBoneLocalRotation.

animator.SetBoneLocalRotation(HumanBodyBones.Head, newHeadRot);

Everything works as expected but there’s one problem I really have no idea how to solve: when I stop setting head local rotation by script, the animator takes back control of the head, changing the head local rotation abruptly. (which is expected but NOT desired)

my question is: How can I smoothly switch from my custom rotation to the animator one?


video reference: - YouTube

0:08 → right after the charachter starts running: the script slowly changes the assigned rotation to Quaternion.Identity and when it reaches that state, it stops to set head local rotation to a new value

0:10 → right after the character stops: the script (re)start assigning new rotations to the head local rotation

note: the problem occurs when the control of head rotation switches from animator to script (and viceversa)


I would assume that you are doing this in LateUpdate(). That is where I do it. To smoothly move between the 2 I use masks for some things and gradually set the weight back to 0.0f when I want to give control back to the base layer or another layer. If you can’t or don’t want to use masks for whatever reason, you will have to do the same, but with slerp for example. When I’m using my custom rotation, I save my lastRot every frame and and slerp to my target and when I want to give control back to the animator, I still save the lastRot, but my target rotation is the actually rotation before masking/customRotation is applied. So it looks something like this:

float timer = 0.0f;

LateUpdate()
{
targetRot = transform.rotation;

transform.rotation = Quaternion.Slerp(lastRot, targetRot, timer);
timer = timer + Time.deltaTime;
lastRot = transform.rotation;
}

Hope that helps