Rotating an object over time to face another object.

I have a problem that I’ve yet been able to solve, and although I know how to approach the problem, I don’t know any Vector math to know if I’m doing the mathematics right.

I have a camera (C) that is always facing the same direction. I have an object (A) with a child (B). A can face any direction in the XZ-plane, and B can face any direction relative to A in the same local XZ-plane. A and B orientation, so their Up direction is the same always. However A can tilt relative to C.

The Problem: How do I rotate Object A so that object B will face the camera at the end of the rotation regardless of which direction B is facing?

My current approach:

I find the angle between the forward vector of the Camera C and A, and the angle between the A and B. I then rotate A based on the combined difference (this part I’m not sure)?

private async Task RotateCartToCamera(ARDrawerData _drawer)
    {
        float angleCamToDrawer = Vector3.Angle(nonARCamera.gameObject.transform.forward, _drawer.gameObject.transform.forward);
        float angleCartToDrawer = Vector3.Angle(arGameController.Cart.transform.forward, _drawer.gameObject.transform.forward);
        float total = angleCamToDrawer + angleCartToDrawer;

        if (total > 180f)
            total = -(180 - total);

        Vector3 startRot = nonARCartRotate.transform.forward;
        Vector3 destRot = nonARCartRotate.transform.forward + new Vector3(0f, total, 0f);
        ARTestModeStatics.DebugMessage("Angle : " + Vector3.Angle(startRot, destRot));

        while (Vector3.Angle(startRot, destRot) > 1f)
        {
            if (cancel.IsCancellationRequested)
                break;

            startRot = Vector3.RotateTowards(startRot, destRot, Mathf.Rad2Deg * rotateSpeed * Time.deltaTime, 0f);
            nonARCartRotate.transform.localRotation = Quaternion.Euler(startRot);       
            ARTestModeStatics.DebugMessage("Angle: " + Vector3.Angle(startRot, destRot));

            if (Vector3.Angle(startRot, destRot) <= 1f)
            {
                ARTestModeStatics.DebugMessage("Rotation completed.");
                nonARCartRotate.transform.localRotation = Quaternion.Euler(destRot);
                break;
            }

            await Task.Delay(1);
        }
    }

This code isn’t giving me the results I expected. Its rotating wrong, and the final angle is completely off. What am I doing wrong? Or is there an easier approach to this? I’m trying not to use Quaternions because I don’t understand any of it.

Id probably just do a simple lerp, this might work

using System.Collections;
using UnityEngine;

public class SimpleLerp : MonoBehaviour
{

    public void LookAtTarget(Vector3 target, float moveSpeed)
    {
        GameObject thisTranform = new();

        thisTranform.transform.SetPositionAndRotation(this.transform.position, this.transform.rotation);
        thisTranform.transform.LookAt(target);
        StartCoroutine(TransformTarget(thisTranform.transform.eulerAngles, moveSpeed));
    }


    IEnumerator TransformTarget(Vector3 newRotation, float moveSpeed)
    {
        //Reset the timer and get the starting rotation
        float timeElapsed = 0;
        Vector3 startingRotation = transform.localEulerAngles;

        //move to the new rotation
        while (timeElapsed < moveSpeed)
        {
            transform.localEulerAngles = Vector3.Lerp(startingRotation, newRotation, timeElapsed / moveSpeed);
            timeElapsed += Time.deltaTime;
            yield return null;
        }
        //make sure we got all the way
        transform.localEulerAngles = newRotation;
    }
}

Thanks! I’ll give that a try.

But I think I’m actually overcomplicated the problem. Since the Camera doesn’t move, I don’t need to knoew the angle between it and object A. A is the only thing that is rotating, I just need to know how much its rotated, then subtract the angle that Object B is relative to it. :stuck_out_tongue: