Spine Rotation Based off Camera

Okay, so I’ve been having trouble with this and have googled it quite a bit but haven’t found anything that helps 100%. I have gained some knowledge like in order to change the biped bone position/rotation you have to do it in a lateupdate rather than the update function itself. So I tried doing this with a simple bit of code

public Transform Spine;
void LateUpdate()
{
      Spine.transform.Rotate(30, 0, 0);
}

This worked making the spine bone lean back so the character was looking up. So I gained that knowledge. But then I tried to apply it using first Quaternion and EularAngles and found it either didn’t work, or worked the wrong way and/or was inconsistent for some reason such as the bones rotating on a side axis only none stop spinning the character. So I tried to dumb it down using a float and defining that float as the camera’s rotation, then changed the bone/spine to rotate based off that float. This resulted in nothing happening even with a basic float. I used

Spine.transform.Rotate(SpineX, 0, 0);

after defining SpineX using

public Transform CameraControlObject;
public float SpineX;
//the SpineX part below was in my update function
SpineX = CameraControlObject.transform.rotation.x;

So then I tried simply even dumbing it down even more by just doing

Spine.transform.rotation = CameraControlObject.transform.rotation;

But the issue here is the orientation of the spine doesn’t match the camera’s rotation.

What is the spine attached to? If the spine is attached to something, you may actually want to modify its localRotation instead of rotation (which is world space).

By default, transform.Rotate works in local space.

The spine is just the biped spine which is a subchild of the character object which contains the bones and the model. It also has children of its own (more bones).

As for the local space and world space I thought maybe that may be why it’s coming out awkward with the last one I tried. But when I tried to do the transform.Rotate it worked with numbers Ex: Spine.transform.Rotate(0,0,30); but not with a float based off the camera’s rotation. I thought this was quite odd and even did a debug but couldn’t find why he wouldn’t rotate.

Yeah still no luck. But I think you may be right. I think it is a local/world rotation orientation issue as the camera is part of its own object and the spine is likewise.

First of all

SpineX = CameraControlObject.transform.rotation.x;

Rotation is a quaternion, just grabbing the x is probably not doing what you want it to do. You probably want transform.eulerAngles.x.

It’s still not going to work correctly with transform.Rotate though, as Rotate is a relative rotation to the current orientation.

This should work though, if you are only trying to match the camera rotation

Spine.transform.rotation = CameraControlObject.transform.rotation;

What is the problem with this? Is the CameraControlObject attached directly to the camera?

I actually did use quaternions and EulerAngles when I first started like I said at the start.But it had inconsistent effects such as not rotating at all or rotating awkwardly which I believe was because of the local/world rotation differences.

The problem with the 2nd one is the character bends to the side and looks directly up with an awkward spine movement that does not mimic the camera rotation. But this also may be because of the local/world rotation differences. The camera is within an object called “Camera Controller” which I grab by doing the following.

public Transform CameraControlObject;

I grab it like this because my code is not on the camera, but the character model. But also note, I am grabbing the “Camera Controller” object I made NOT the camera itself as the controller is the one rotating. The issue is with both Quaternions/EulerAngles and transform.rotation methods I can’t get the spine to rotate correctly based off an objects rotation or variable. If I use the transform.Rotate with a simple set of numbers it works. But place a set of variables in there defined as numbers and it doesn’t work at all or correctly.

As long as you do Spine.transform.rotation = CameraControlObject.transform.rotation; it should match the rotation of the CameraControlObject exactly, as you are both grabbing the world space rotation and setting the world space rotation.

That’s what I said. The simplest form to force it to look the same direction. But this is what ends up happening. And when I check the rotations in the inspector they do not equal the same. Not really sure why.

Ah HA! Figured it out partially. It has to do with orientation of the bones which I never thought to check before. The bones imported with their axis’ pointing different directions than the orientation of the camera controller object. So it is doing exactly as it should. I assumed the orientation for my bones were set to the natural orientation within unity and they were not.

Okay, so I basically worked my way around this issue. The problems still persist when I attempt to make the spine move with the camera using Quaternions/EulerAngles but it must be because I’m just doing it wrong. I have managed though to get the basic rotation equaling rotation method to work now that I noticed and have corrected the spine orientation.

Glad to hear you’ve figured it out.

Just remember to keep track of what bones are attached to, and a bone’s local rotation is always relative to its parent. It’s a lot safer to stick with local rotations using bones, otherwise you’ll go mad trying to figure it all out…

1 Like

You can try something like this I think

spine.rotation = Quaternion.LookRotation(Camera.main.transform.forward, spine.up);

Or spine.forward/spine.right depending on the direction of the bone.