Bones not rotating correctly to angles of physics GameObjects

This is a stripped-down version of the code I’m using (and it does the same thing as the full version, I tested):

#pragma strict

var BoneRoot : GameObject;

private var Root : GameObject;
private var Root_PosOffset : Vector3; //the offset of the collider/rigidbody from the actual bone
private var Root_RotOffset : Vector3;

function Start()
{
	Root=GameObject.Find("Root");
	Root_PosOffset=Root.transform.position-BoneRoot.transform.position;
	Root_RotOffset=Root.transform.eulerAngles-BoneRoot.transform.eulerAngles;
}

function Update()
{
	BoneRoot.transform.position=Root.transform.position-Root_PosOffset;
	BoneRoot.transform.rotation=Quaternion.identity;
	BoneRoot.transform.Rotate(Root.transform.eulerAngles-Root_RotOffset,Space.World);
}

What I’m attempting to do is record the offset of the collider (the GameObject variable for which is filled within the inspector) from the bone (position and rotation), then in Update(), after the collider (which has a rigidbody also) has moved, position and rotate the bone to the new position/rotation, minus the offset. What I get is the bone rotates weirdly, not entirely randomly, a bit like it’s using the wrong axes. The positioning works, though.

What could be causing this? Have I done something stupid in my code? Any help would be much appreciated :slight_smile:

------ Additional Info ------

What I’m trying to do, specifically, is to control a rigged character by physics, in much the same way as a ragdoll. I don’t use the built-in ragdoll facilities because I will need more control in future.

Feel absolutely free to ask for more details if you can’t see anything wrong with the code.

Finally!! Yes! It is SOLVED! :smiley: :smiley:

After many, many hours of thinking, experimenting, frustration, and of sitting in front of a fireplace turning invisible objects in the air with my hands, I finally realised Eulers didn’t work the way I thought they did…that is, I finally realised that they can in fact fail. Not only that, I realised that the order in which the rotation on each axis is applied is incredibly important, as well as the reference frame used for each axis.

So I started thinking. I had the words “at the one time” stuck in my head from some description of Quaternions, and realised that I needed to work directly with Quaternions. I also remembered that to “add” the angles of a Quaternion together, you multiplied them together. I needed to be able to find the difference between two rotations, so I headed straight for the Unity docs to see if the Quaternions had a / overload. Sad, no they didn’t. So I started searching for a way to “subtract” Quaternions, and found the answer to this question. It sounded hopeful, so I immediately replaced any and all Euler code with Quaternion code, and…

It worked.

I still didn’t get my hopes up until I had tried every possible combination of angles and parenting, but in the end I couldn’t make it fail. It just… worked!

So after these days of frustration, this is the solution:

#pragma strict

var BoneRoot : GameObject;

private var Root : GameObject;
private var Root_PosOffset : Vector3; //the offset of the collider/rigidbody from the actual bone
private var Root_RotOffset : Quaternion;

function Start()
{
	Root=GameObject.Find("Root");
	Root_PosOffset=Root.transform.position-BoneRoot.transform.position;
	Root_RotOffset=Quaternion.Inverse(Root.transform.rotation)*BoneRoot.transform.rotation;
}

function Update()
{
	BoneRoot.transform.position=Root.transform.position-Root_PosOffset;
	BoneRoot.transform.rotation=Quaternion.identity;
	BoneRoot.transform.rotation=Root.transform.rotation*Root_RotOffset;
}

Short and sweet: Don’t use Eulers unless you absolutely have to set angles directly. If you’re just modifying angles with other angles, use Quaternions.