- Home /
How to rotate bone relative to camera using LookAt
Hi. I've been struggling with this for a while now. I want my character's arms to face the opposite direction of the camera. He's supposed to aim wherever the camera looks, in third person. Preferably using LookAt(), because I (think) I understand how to use it. The problem though, is that the bones I want to rotate have really messed up axes. Both me and a friend tried to change the orientation of the bones local axes in Blender, but it seems that it is not possible. Here is a picture of how the right upper arm bone's axes look:
As you can see, the z axes points up, when it should really point out of the arm. The +y axis points where -x should be and -x points where +z should point. When I use LookAt, I naturally get some weird results. If the axes where correct, I believe i would write the script something like this?
function LateUpdate () {
direction = Vector3(0,0,1);
direction = cameraTransform.TransformDirection(direction);
transform.LookAt(transform.position+direction);
}
I'm not at a computer where i can test this right now, so please correct me if i'm wrong. This would take a forward direction and transform it so that it is the camera's forward, and then apply it to the bone. Right? Well, this doesn't work, as the axes are messed up. How should I go about making the bone rotate to always face the camera's forward direction?
If I understand LookAt() correctly, it rotates the object's z axis to the target specified, and then it rotates the object's y axis to point in either world up direction, or the up direction specified. Is this correct?
Bones always have their Y axis along their length. While it's possible to change that, don't do it because the headache of implementing that is not worth it.
The easiest fix is to make a control object rotated such that its +Z is along the bone's length, then child the bone to the control. Then you can rotate the control with LookAt and not worry about fancy quaternion math.
Answer by alexanderflink · Apr 09, 2013 at 03:12 PM
Thank you, but this didn't really produce what I want (for the arm bone to point in the opposite direction of the camera). I changed the code to this
direction = Vector3(0,0,1); direction = cameraTransform.TransformDirection(direction); transform.LookAt(transform.position+direction); transform.forward = transform.right;
And that did make the arm bone face the opposite direction of the camera horizontally, but it always stays the same vertically. However, I then also added this code: transform.eulerAngles.z = cameraTransform.eulerAngles.x;
Since the bone's right axis is it's z axis (which is messed up), that code makes it rotate vertically with the camera. My problem seems to be solved. I wish however, that there was some way to conform these weird axes on the bones to Unity's z-forward standard.
Answer by IronFurball · Apr 09, 2013 at 08:49 AM
Put this in a script, and place that script on the object that you want to face in the camera's direction.
void LateUpdate () {
transform.LookAt(transform.position+Camera.main.transform.forward);
}
I'm sorry, this doesn't help at all. This is what I was trying to do from the start. It doesn't work because the bones forward axis is not z, and it's up axis is not y.
Does anyone have a solution on how to rotate the bone relative to the camera, even though it's axes are not following the Unity standard?
Depending on what 3d program you used, often when you're exporting the model you can check an option somewhere that says something like, "z is up" or "don't convert up axis".
Try using that when exporting to see if it changes anything.
One other thing you could do, but will probably be a lot of work, is:
putting the bone you want rotated into an empty game object.
rotate your bone so that it faces the forward axes of the empty game object.
use the code above on the empty game object.
The .fbx export settings don't really make any difference. If I set the "forward" option to Z in the exporter (Blender), it just turns the entire model, not the individual bones.
I tried creating an empty game object and making it the parent of the bone, but that created some unwanted distortion of the limbs etc. There absolutely HAS to be a way to fix this, I mean... how do people who do professional games in Unity handle rotating bones, since there seems to be no way to make the bone's local z axis face forward?
Bones can sometimes be a hassle to deal with, it also depends on the 3D program you're using I guess.
But what whydoidoit posted below seems worth a shot, why don't you try that.
Answer by whydoidoit · Apr 09, 2013 at 01:57 PM
Try doing the LookAt and then doing
transform.up = transform.forward
Although you may need to control the rotation around the facing axis too (the rotation in localEulerAngles.y) after that