I have 4 objects, two planes and two arrows. One arrow points at one of the planes, and I want the second arrow to match the first arrow, but relative to the second plane. What I mean by this, is if the first arrow is moved 1 unit to the right relative to the first plane, the second arrow should move 1 unit to the right relative to the second plane. I have gotten the positions to work out correctly, but I can’t figure out how to match the rotations. Some axes of rotations work correctly some of the time, but once one of the planes are rotated, the second arrow’s rotation gets more out of sync with the first.
Here’s the code that I’m using to test this, with the best I could figure out:
[ExecuteInEditMode]
public class RotationTest : MonoBehaviour
{
public GameObject target;
public GameObject camera;
public GameObject arrow;
void OnWillRenderObject()
{
if (!target || !camera || !arrow) return;
arrow.transform.position = target.transform.TransformPoint(transform.InverseTransformPoint(camera.transform.position));
arrow.transform.rotation = Quaternion.Inverse(camera.transform.rotation) * transform.rotation * Quaternion.Inverse(target.transform.rotation);
//arrow.transform.eulerAngles = new Vector3(arrow.transform.eulerAngles.x, -arrow.transform.eulerAngles.y, arrow.transform.eulerAngles.z);
}
}
I put this script on the first plane, the first arrow is ‘camera’, the second plane is ‘target’, the second arrow is ‘arrow’. When both planes are aligned exactly, the second arrow should be exactly the same position and rotation as the first. The commented out lines cause the arrow to match each axis of rotation individually (I think), but when multiple axes are rotated, it gets out of sync.
When both planes are facing the same direction, simply setting the rotation of the second arrow to the first arrow’s rotation works correctly, but once the first plane is rotated this method falls apart.
I’ve been at this for quite a while, trying different combinations of Quaternion multiplications, but I can’t seem to figure it out. I originally tried doing the same thing with the rotation that I did with the position (using TransformDirection), but I couldn’t get that working either. Any help at this point is much appreciated.
[Edit]: I was able to get the arrows to match when the two planes are at the same position and orientation using the following code
arrow.transform.eulerAngles = target.transform.TransformVector(transform.InverseTransformVector(camera.transform.eulerAngles));
however, this breaks once either one of the planes are rotated. It does the same thing as setting their rotations equal to each other, but it differs when a plane is rotated, causing the arrow to rotate in very strange ways. Trying this with same idea with TransformDirection and the camera’s forward vector does not yield the expected results.
Edit2: I was able to get the arrow to match correctly when the planes are rotated in only a single axis of rotation (about the Y axis) with arrow.transform.eulerAngles = (target.transform.eulerAngles - transform.eulerAngles) + camera.transform.eulerAngles;
but this still breaks when one or both of the other axes are rotated. Here are a few pictures describing what I’m trying to achieve, and what is actually happening with the latest code: Rotation Tests - Album on Imgur