Trying to calculate the required relative rotation...

Hey guys,

New to Unity, currently in the midst of animating some character movement with the player camera in an isometric type view.

At the moment, I am working on the forward animations. I have made three base animations for the foward motion, (legs running forward, body facing forward; legs running forward, body facing right; legs running forward body facing left). The ultimate goal is that the legs will appear to run in the direction of movement, and the upper body will rotate to the direction of the mouse cursor, using animation weights (I do not want to rotate the bone manually).

The problem I am having is this:

At the moment, I have written a script which rotates the root of the model in the direction that the player will run. So, if the player runs to the right, the model is rotated in that direction.

The goal now is, to take the other to animations (facing left, facing right) and change the weighting of the animations so that when the cursor rotates round the player, the weighting changes how far the player’s upper body is facing left and right.

I understand wighting, and everything else discussed up until this point.

My problem is, I am really struggling to work out how I calculate what angle the character should be facing RELATIVE to the current rotation of the model root. The closest I have managed to get is using Quaternion.Angle() which actually works to return the relative angle, however it does not return it based on a posative/negative required rotation.

For example, if my character is facing directly north (eular 0 on the y axis) if my mouse cursor is directly right to the model, Quaternion.Angle() returns 90, which is perfect! However, if the mouse cursor is directly left of the model, it also returns 90, not -90.

I could write a script to detect whether the cursor is on the left/right side of the model, and just change the value to negative if the cursor is on the left, however as far as I can tell, this would require scripting for all possibly movement directions…

So, the ultimate question here is, how can I get the value of rotation required to rotate either to a position, or desired rotation, relative to the current rotation?

Please do not suggest using something like locomotion, or something which calculates all of this for me.

Many many thanks in advance for any suggestions!

You should use Vector3.Angle, which has the same problem, and Vector3.Cross to find the angle polarity: the cross product of A and B is a vector perpendicular to both, and will point up when B is to the right of A, or down when it’s to the left - thus we can inspect its Y coordinate to find the polarity.

Supposing that moveDir is the direction it’s moving and lookDir is the direction it’s looking at:

  // moveDir and lookDir are Vector3
  var angle: float = Vector3.Angle(moveDir, lookDir);
  if (Vector3.Cross(moveDir, lookDir).y < 0) angle = -angle;

This code assumes that Y is the up direction, and that moveDir and lookDir are roughly horizontal (actually, this will work even if both are indecently non-horizontal - they can’t only form a vertical plane).

Edit: Whoops, misread the question; take this as an alternative approach. I haven’t worked with weighted animations to accomplish this sort of thing.

If you’re going to be modifying bone rotations to get these animations working (and I’m not entirely certain there’s any other way to do it), you can use a simple transform.LookAt, assuming the bones are set up ‘correctly’.

Whatever bone influences the part of the character which you are rotating needs to have its +Z axis facing exactly character-forward when at rest. (So if it’s the spine base, +Y is towards the head, +X is towards a hip, and +Z is the direction the character would walk forward).

You can then use boneGameObject.transform.LookAt( directionVector ) to point the entire rotational part of the character in the indicated direaction.

Note that Blender automatically writes positional animation whether or not the bone is rotated, so you’ll need to do your rotation in LateUpdate every frame, or else you’ll need to fix Blender’s FBX exporter to not export animation for non-animated bones (it’s a simple fix in 2.49b, but I don’t know about higher versions)

You, my friend, are a legend!

Thank you very much!!