- Home /
Rotate Z axis of object to camera
Hello guys, I'm having trouble making all connections (3 cylinders with ball) is facing the camera. The core (central sphere) rotates according to the mouse, and when this happens connections must rotate along with the nucleus always turning the cylinders at the camera.
What happens:
What I need:
Code used in connections:
var angle;
function Start() {
}
function Update () {
var center : GameObject = GameObject.Find("centro");
var dx = transform.position.x - Camera.main.transform.position.x;
var dy = transform.position.y - Camera.main.transform.position.y;
var radians = Mathf.Atan2(dy,dx);
if(center.transform.rotation.eulerAngles.x >= center.transform.rotation.eulerAngles.z)
{
angle = radians * 180 / Mathf.PI - (center.transform.rotation.eulerAngles.x/2*-1);
}
else
{
angle = radians * 180 / Mathf.PI + (center.transform.rotation.eulerAngles.z/2);
}
var rotateZ = Mathf.LerpAngle(transform.rotation.z, angle, 0);
transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.Euler(transform.rotation.eulerAngles.x,transform.rotation.eulerAngles.y,rotateZ),1);
}
For 50% of angles this code works. In other cases the object is in the wrong rotation.
Answer by ncallaway · Jan 05, 2014 at 08:33 PM
For this answer, I'm going to set up a coordinate system. If this coordinate system is different from the one that you've implemented, then be sure to change the axes! Also, I'm assuming that Z, Y, and X are normalized.
For this answer Z will point in the long direction of the cylinders (i.e. the axis you want to rotate around), Y will point perpendicular to the plane that the cylinders are arranged in (i.e. the axis you want to point toward the camera), and X will be the remaining axis. The last vector that we'll need is the direction the camera is facing.(camera.forward).
So, now the goal is to rotate the object around the Z axis, such that the Y vector is as closely aligned wlink textith cameraForward as it can be.
With the constraint that we can only rotate around Z, we can only make Y point somewhere along the plane that is defined by having a normal of Z. So we will project camera.forward to the plane defined by Z, and call this projected vector our Y-Target.
Lastly, we'll need to come up with a rotation that goes from Y to Y-Target. Fortunately, there's a built in function that does that for us!
void Update()
{
// Project cameraForward onto the plane, to get our target.
Vector3 yTarget = Camera.main.transform.forward - (transform.forward * Vector3.Dot(Camera.main.transform.forward, transform.forward));
// Find the needed rotation to rotate y to y-target
Quaternion desiredRotation = Quaternion.LookRotation(transform.forward, yTarget);
// Apply that rotation
transform.rotation = desiredRotation;
}
Edit: I had trouble getting the details right without a sample project. I created a quick sample project, implemented this code and attached it. You should be able to open and run the sample project, and see that it does what you want.
Sorry for all the back and forth!
@ncallaway: $$anonymous$$any thanks for the help! Your explanation is excellent.
The code generated some errors:
Assets / teste.cs (15,47): error CS1061: Type UnityEngine.Camera 'does not contain a definition for
forward' and no extension method forward 'of type
UnityEngine.Camera' could be found (are you missing a using directive or an assembly reference?)
Assets / teste.cs (21,27): error CS1502: The best overloaded method match for UnityEngine.Transform.Rotate (UnityEngine.Vector3, UnityEngine.Space) 'has some invalid arguments** **Assets / teste.cs (21,27): error CS1503: Argument
# 1 'can not convert` UnityEngine.Quaternion' expression to type `UnityEngine.Vector3 '
Could you help me solve?
Thank you!
Online version of my code: http://www.agenciadetalhes.com.br/molecule/
Use mouse to control orbit!
I edited the code so that it shouldn't have the errors you're seeing.
The changes I made were the exact same changes Nakor made below. That is replacing rotation with rotation.eulerAngles (because transform.Rotate takes euler angles), and Camera.main.forward with Camera.main.transform.forward.
@ncallaway: VERY VERY $$anonymous$$UCH THAN$$anonymous$$S!
Answer by Nakor · Jan 05, 2014 at 09:51 PM
void Update()
{
// Project cameraForward onto the plane, to get our target.
Vector3 yTarget = Camera.main.transform.forward - (transform.forward * Vector3.Dot(Camera.main.transform.position, transform.forward));
// Find the needed rotation to rotate y to y-target
Quaternion rotation = Quaternion.FromToRotation(transform.up, yTarget);
// Apply that rotation
transform.Rotate(rotation.eulerAngles, Space.Self);
}
ncallaway put incorrect code. I haven't tested this but I think it should be correct.
Erro in this line: transform.Rotate(rotation, Space.Self);
Assets/teste.cs(21,27): error CS1502: The best overloaded method match for UnityEngine.Transform.Rotate(UnityEngine.Vector3, UnityEngine.Space)' has some invalid arguments Assets/teste.cs(21,27): error CS1503: Argument
#1' cannot convert UnityEngine.Quaternion' expression to type
UnityEngine.Vector3'
I also had tried to correct the Camera.main.transform, but this line continued with the problem!
Sorry try this: transform.Rotate(transform.rotation.eulerAngles, Space.Self);
I need use variable rotation created by @ncallaway.
In this code transform.Rotate(transform.rotation.eulerAngles, Space.Self); the variable is replaced!
No big deal just use rotation.eulerAngles rather than transform.rotation.eulerAngles I already edited my original post to show how it should look.
Your answer
Follow this Question
Related Questions
Rotate object around local Z axis 1 Answer
Rotate exactly on time 1 Answer
Image Rotate Gallery Snap 0 Answers
Rotate around obsolete - missing Rotate overloads??? 2 Answers
rotating player 180 degrees 0 Answers