- Home /

# Rotation problem while dynamically changing animations

I am trying to implement animation mirroring for a character model. The model uses an $$anonymous$$erarchy of bones and has a skinned mesh. The models original orientations and having to deal with a $$anonymous$$erarchy of bones gave a lot of headache w$$anonymous$$le implementing the mirroring, but in the end I managed to get it working.

To change the animation dynamically I change the rotation and position of bones in the LateUpdate function of a script that is placed on the same object that has the SkinnedMeshRenderer placed on it. I almost have the mirroring of the character working. However there is a one problem I am unable to solve.

At some point during the mirroring of the animation, the root bone (in top of the $$anonymous$$erarchy) suddenly flips/snaps making my character model twist badly in the area of the root bone. The root bone is even rotating in the wrong direction at some point.

In my script I calculate the new rotation of each bone and the rotation I calculate is correct. However when I apply t$$anonymous$$s rotation to the bone, it is changed into another rotation by Unity. An example would be (pseudo code, but actual values from Debug.Log):

```
Vector3 mirrRot = new Vector3(267.4f, -232.4f, 189.8f); // correct mirrored rotation
Quaternion mirrored = Quaternion.Euler(mirrRot); // create a quaternion using the correct euler rotation
// lets see what the actual rotation of the root bone looks like
Debug.Log(mirrored.eulerAngles);
// mirroring should be applied over (270, 90, 0) as t$$anonymous$$s is the original bone orientation
// unmirrored value: (272.6, 52.4, 189.8)
// expected value: (267.4, -232.4, 189.8), note that -232.4 equals 127.6
// actual result: (272.6, 307.6, 9.8), output of the Debug.Log statement above
```

I guess there is some quaternion magic happening here. I suspect somet$$anonymous$$ng like (x, y, z, w) becoming (-x, -y, -z, -w) or somet$$anonymous$$ng like that. The expected euler rotation and the actual euler rotation might be the same (I'm unsure tbh). However it totally ruins the model (causing a twist and a rotation in the wrong direction) w$$anonymous$$le animating it.

All other bones in the $$anonymous$$erarchy are working perfectly fine and are mirrored as expected (but t$$anonymous$$s might be pure luck of course ;-)).

I also tried throwing overboard the euler angles and doing the entire calculation with quaternions. However the problem was exactly the same. Does anybody have a clue how I would be able to fix t$$anonymous$$s? Is there any way to let Unity use the exact euler angles I calculated (and about w$$anonymous$$ch I know they are correct)?

**Answer** by aldonaletto
·
Jul 18, 2011 at 01:34 PM

These results are correct: Euler(267.4, -232.4, 189.8) and Euler(272.6, 307.6, 9.8) give the same rotation. There are several (infinite?) combinations w$$anonymous$$ch result in the same rotation: rotating 180 around Z plus 180 around X gives the same result as rotating 180 around Y (but it's a stupid way to do that, for sure!). The two Euler angles you t$$anonymous$$nk are different actually represent the same rotation.

A commom error is to assign a rotation to some object w$$anonymous$$ch already was rotated from its original orientation - the new rotation replaces the older one, and the object is rotated *from its original orientation*, not from the present one. If you want some object to be rotated from its present orientation to a new one, you must *combine* the old and the new rotations:

```
transform.rotation = transform.rotation * Quaternion(10, 20, 30);
```

T$$anonymous$$s will *combine* the rotations (not multiply them).

I'm a complete stupid about animation, so I just can't tell you how to rotate the bones, but the basic idea probably applies to your case.

Thank you for taking the time to answer. I am aware I am replacing the rotation, this is what I intend to do.

Perhaps the calculation of the mirroring is not correct. I assumed I could mirror x and y euler angles over initial x and y rotations (never touch the z euler component). However in my animation the Euler representation is changed at some point:

z rotation jumps from 0 to 189

y rotation jumps from 241 to 52

The visible change in rotation is just a small one, so it must be a change to another Euler representation which probably influences my mirroring algorithm in some way (ignoring/leaving the z component is no longer valid).

I'll have to think this through more thoroughly and see if I can come up with a more general approach to mirroring the rotation.

**Answer** by Heiko
·
Jul 22, 2011 at 07:28 AM

I managed to get it working properly in the end. Switched back to using quaternions and did the mirroring in the following way:

Store original position of each bone in the $$anonymous$$erarchy.

Calculate bone order in $$anonymous$$erarchy (rotation will start at the root bone).

In LateUpdate store the current rotation of each bone.

Start mirroring at the root bone and work your way down to the bottom of the $$anonymous$$erarchy.

Calculate difference between original and current rotation:

`Quaternion fromOrigToCurr = Quaternion.Inverse(original) * current;`

Mirror the difference rotation:

`Quaternion mirror = new Quaternion(1, 0, 0, 0);`

`Quaternion fromOrigToMirrored = mirror * fromOrigToCurr * mirror;`

Rotate from orignal to mirrored position:

`Quaternion mirroredRot = original * fromOrigToMirrored;`

T$$anonymous$$s worked on either rotation or localrotation of the bones. The mirror quaternion I had to use for the bones was not exactly the same for each bone because there were some weird rotations between bones (all bones below the root bone needed another mirror Quaternion, I t$$anonymous$$nk it was Quaternion(0, 0, 1, 0) or so.

For all bones that had a left and right side version, I just had to mirror the rotation and place it on the bone on the other side (no need to calculate difference between original and current).

In the end it appeared that the bones also had their positions animated w$$anonymous$$ch I didn't expect (I assumed bones only had a rotation, except the root bone that would move the entire skeleton). T$$anonymous$$s caused some weird looking mirrored animations, so the positions of the bones had to be mirrored as well (fortunately t$$anonymous$$s is much easier than mirroring rotations).

### Your answer

### Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

### Follow this Question

### Related Questions

Can't Accurately Read Rotations 0 Answers

c# modify only one axis of a quaternion 2 Answers

Detecting Opposite Rotations of two Pipes 1 Answer

eulerAngles not set to zero. 1 Answer