- Home /
Look at object with a single axis while moving.
Ok, so I have a central object (an arrow) that rotates around a circle, pointing towards the direction the camera is facing. I have an empty gameObject parented to the center of the camera as a reference Vector3 to look towards. The arrow is a Sprite, so it's only supposed to be rotating on the Z-axis. Using a few snippets I found, I managed to get it working perfectly with this:
var newRotation : Quaternion = Quaternion.LookRotation(facingVel.transform.position - cursorObj.transform.position, Vector3.forward);
newRotation.x = 0.0;
newRotation.y = 0.0;
facingVel.transform.localRotation = newRotation;
The problem I have now is that the player object must be able to rotate, however as soon as the player isn't at 0,0,0 rotation, this throws off the above code and the arrow begins drifting, due to the position of the target in world space. The arrow is also parented to something, if that helps. Any ideas?
EDIT: I still haven't found the solution, however after exposing some of the values, I've noticed that the Z and W components of the newRotation variable change significantly as the player object is rotating.
$$anonymous$$aybe try: facingVel.transform.rotation = newRotation;
Okay, two quick questions:
1) Is your camera always looking straight along the Z-axis, or does the camera move and rotate fairly freely?
2) Sorry, I guess it's not actually a question. Don't try to manipulate Quaternions by hand unless you're certain you really, REALLY know what you're doing. Setting the x and y to zero and not understanding the result is usually indicative of treating quaternions like vectors. (They're not)
The camera doesn't exactly move per-se, though the object it's parented to does. Other than that, the camera has full rotation on each of the axis.
I have tried to understand Quaternions, but as most people have said, it's not worth trying to understand them. The code I was using was based off a similar problem (facing something but limited to one axis). I've since changed it to this:
var newRotation : Quaternion = Quaternion.LookRotation(facingVel.transform.position - cursorObj.transform.position, Vector3.forward); facingVel.transform.localRotation = newRotation; theRotation = newRotation; facingVel.transform.localRotation.x = 0.0; facingVel.transform.localRotation.y = 0.0;
Which simply constrains the X and Y rotation, however this has the same result. As soon as the parent starts moving/rotating, the arrow begind drifting and no longer faces the camera-center.
Hmm... Okay, I think I need to start from the top, then...
Ok, so I have a central object (an arrow) that rotates around a circle, pointing towards the direction the camera is facing.
The arrow is also parented to something
Does this mean it's like a compass? You mentioned another GameObject as a child of the camera, so is this arrow orbiting around that?
Answer by MasterRIP · Aug 10, 2015 at 03:42 AM
attach the object to your camera
The object is supposed to point towards the camera, so parenting it would defeat the purpose entirely.
Answer by Eno-Khaon · Aug 15, 2015 at 06:24 AM
Okay, I think I understand well enough what you're trying to do. Sorry I haven't been able to follow your train of thought on this as well as you might like. If it's not exactly what you're needing, hopefully this will at least get you pointed in the right direction.
Going along with the idea of a compass again, what you'll need are:
1) Your script will need to know the camera's current heading, so you'll probably want a Transform variable to hold that.
2) You'll need to know the local orientation of your square pointing you in the right direction. I'll assume that no rotation faces towards a camera with no rotation.
So, here's my general idea of how to approach this, on the basis that it's a fixed-orientation compass.
var mainCam: Transform; // Connect your camera to this either through the editor or script
// ...
facingVel.transform.localEulerAngles = Vector3(0, 0, Mathf.Repeat(mainCam.eulerAngles.y, 360.0));
Based on the criteria mentioned above (especially #2), this is a very simple and straightforward approach to directly converting the Y-axis rotation of the camera to the Z-axis rotation of the arrow. If the arrow is indeed already a child of the player and/or camera in some capacity, then it should be able to rotate with local rotation alone.
If it needs more than that, however, a slight tweak can potentially be employed instead:
facingVel.transform.rotation = Quaternion.LookRotation(mainCam.position - facingVel.transform.position, Vector3.up); // Set a new forward direction to face the camera
facingVel.transform.rotation *= Quaternion.AngleAxis(Mathf.Repeat(mainCam.eulerAngles.y, 360), transform.forward);
I believe I got the order right on this, at least. As Quaternion math is non-commutative, it can be easy to mix up the exact order of operations.
This version faces the arrow toward the camera with "world up" as its upward direction. Then, it rotates the arrow while facing directly toward the camera to match the degrees of rotation, acting as an effective compass.
If this still isn't able to get you where you're trying to go with this, just let me know!
Answer by fighder · Sep 18, 2015 at 03:45 PM
var newRotation : Quaternion = Quaternion.LookRotation(facingVel.transform.position - cursorObj.transform.position, Vector3.forward);
newRotation.x = 0.0;
newRotation.y = 0.0;
facingVel.transform.localRotation = newRotation;
So lets look at what you did here: 1. you used lookrotation with agruements of a direction and vector 0,0,1, which is right. 2. You adjusted the rotation's x and y value to 0 to only rotate in z, but this is where you made a mistake. The variable newRotation right now is a Quaternion, it is not the transform.rotation you see on the inspector. You should not ever directly adjust the Quaternion unless you know what you are doing. The correct way to fix this is instead of adjusting x and y the way you did, instead do the following:
facingVel.transform.rotation = newRotation;
facingVel.transform.eulerAngles = new Vector 3 (0,0,facingVel.transform.eulerAngles);
What I did here is applied the newRotation, a Quaternion, to transform.rotation, which is also a Quaternion. The numbers you see in the rotation section on the inspector is really transform.eulerAngles instead. So to make sure no rotation happened on x and y, you just need to adjusted the eulerAngles.
I don't know what exactly you want to do, but this seems to be the main problem.
Your answer
![](https://koobas.hobune.stream/wayback/20220611235035im_/https://answers.unity.com/themes/thub/images/avi.jpg)