1
votes

Background: I am creating an AR treasure hunt app. It is simple, it has a locator that tells you where the treasure is relative to you. I have the camera being the origin and the treasure being an object in AR world.

Question: I would like to rotate my arrow according to where in space the treasure is at. but in 2d. Basically, I would ignore the relative forward plane that is camera.forward.

Example: If the camera rotation is default, the angle can be calculated as atan2(dy,dx). If the camera is looking straight down, the angle is atan2(dz,dx).

What I have tried:

Quaternion lookRot = Quaternion.LookRotation(target.transform.position - origin.transform.position);
Quaternion relativeRot = Quaternion.Inverse(origin.transform.rotation) * lookRot;

Relative rotation is correct in 3d space but I would like to convert that into 2d ignoring the camera.forward plane. So even if the treasure is in front or behind the camera, it should not change the angle.

4
in 2D use angle = atan2(y,x) - MBo
@MBo The world itself is in 3d and the camera rotation changes over time. So I am not sure how do you derive x and y from it, since it is not always pointing straight into the z plane. - Byte
But you wrote about ignoring z. Just project point coordinates onto z=0 plane - MBo
@MBo Thank you, I updated the title. Sorry for the confusion - Byte
Search swing twist decomposition - minorlogic

4 Answers

3
votes

enter image description here

Okay so I’m hoping this makes sense. You’re going to need some sort of if statement to determine if your character is looking along the x, y or z plane. Hopefully the diagram is clear as to what those parameters are but if not. To be looking in the “x” plane for example, the y rotation would have to be between 45° and -45° or 135° and -135° AND the z rotation would have to be between 45° and -45° or between 135° and -135°.

Essentially what you’ve got is a sphere split into six parts, two parts for each plane along which the character could look. Once you’ve determined which plane the character is looking in you can determine the direction by finding the difference in position between the character and the treasure along the two planes the character isn’t looking along. Then use trig to calculate the angle

2
votes

Replying to an old thread, but I was struggling with the same problem and found a relatively simple solution:

Project the position of the target (relative to the origin) on a plane defined by the forward vector of the camera. Then just rotate towards the projected point:

Vector3 diff = target.transform.position - origin.transform.position;
Vector3 projected = Vector3.ProjectOnPlane(diff, Camera.main.transform.forward);
origin.transform.rotation = Quaternion.LookRotation(projected);
0
votes

Calculate the difference in x and y coordinates simply by subtracting transform.x for one object by transform.x of another object and the same process for y coordinates and then use Mathf.atan(difference in y/difference in x) to calculate the angle. Then put the z rotation to this angle and assign the x and y rotation to what they already were.

0
votes

Turns out there is a very simple way to get relative X and Y of the target.

Vector2 ExtractRelativeXY(Transform origin, Transform target) {
    // Get the absolute look rotation from origin to target.
    Quaternion lookRot = Quaternion.LookRotation(target.transform.position - origin.transform.position);
    // Create a relative look rotation with respect to origin's forward.
    Quaternion relativeRot = Quaternion.Inverse(origin.transform.rotation) * lookRot;
    // Obtain Matrix 4x4 from the rotation.
    Matrix4x4 m = Matrix4x4.Rotate(relativeRot);
    // Get the 3rd column (which is the forward vector of the rotation).
    Vector4 mForward = m.GetColumn(2);
    // Simply extract the x and y.
    return new Vector2(mForward.x, mForward.y);
  }

Once obtained x and y, turn it into angle using angle = atan2(y,x) as suggested by both MBo and Tom.

This works because of the matrix components of the quaternion can be demonstrated in multiple vectors. Better illustration is found here https://stackoverflow.com/a/26724912.