How do I rotate a Vector3 based on two other Vector3?


See the picture for a better understanding.
(BTW the example is in 2D but i need this in 3D)

Picture Subtitle:

Red and yellow dot: origins of the vector3

Blue Vector3: Imagine those as a forward vector3 of an object

Green Vector3: A vector3 i obtained from rotating the red dot blue transform

Orange Vector3: the vector3 that i want to obtain, it has the same rotation as the green one but relative to its origin

Purple rotation: Same rotation on both sides

I’ve already tried messing with quaternions but I cant figure how to make this work, when using the quaternions it looked like they were rotating based on the wrong origin…

I think you are trying to obtain the orange vector, and you don’t care about the purple rotation itself? In that case, there is no need to mess with quaternions. You can use the local coordinate systems.

I also think that maybe it’s not working how you want because the ScreenPointToRay method gives you a direction and an origin, and the two have to be used in conjunction. It will be a little off if you just rotate the direction vector, because the origin of the ray is on the near clipping plane, not at the camera position as might be expected.

Here is some code in two behaviors that I think is doing what you want:

public class CameraMouseRay : MonoBehaviour
{
    public Vector3 localDirection { get; private set; }
    public Vector3 localOrigin { get; private set; }

    void Update()
    {
        Ray ray = GetComponent<Camera>().ScreenPointToRay(Input.mousePosition);
        localDirection = transform.InverseTransformVector(ray.direction);
        localOrigin = transform.InverseTransformPoint(ray.origin);
    }
}

public class CameraLocalRay : MonoBehaviour
{
    public CameraMouseRay mouseCamera;

    void Update()
    {
        Vector3 localDir = mouseCamera.localDirection;
        Vector3 worldDir = transform.TransformVector(localDir);
        Vector3 localOrg = mouseCamera.localOrigin;
        Vector3 worldOrg = transform.TransformPoint(localOrg);
        Debug.DrawRay(worldOrg, worldDir * 100, Color.yellow);
    }
}

The CameraMouseRay component goes on the camera that the player is looking through, and the CameraLocalRay component goes on the second camera.

Assuming;

  • Va = Red-Blue
  • Vb = Red-Green
  • Vc = Yellow-Blue
  • Vd = Yellow-Orange

You can think of a quaternion as a rotation - as such, you can just find and store the rotation from Va to Vb and apply the same rotation to Vc;

Quaternion rot = Quaternion.FromToRotation (Va, Vb);
Vector3 Vd = rot * Vc;