Crocsx
Crocsx

Reputation: 7609

Zoom at a certain distance

I have the following Unity Script

void Update()
{
    Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
    RaycastHit hit = new RaycastHit();

    if(Physics.Raycast(mouseRay, out hit))
    {
        if (Input.GetMouseButtonDown(0))
        {
            Camera.main.GetComponent<CameraController>().ZoomIn(hit.transform.position);
        }
    }
}

Then in the camera I Have

public void ZoomIn(Vector3 target)
{
    zoomSavePosition = camera.transform.position;
    StartCoroutine(Zoom(zoomSavePosition, target, zoomDuration));
}


// ZoomRoutine
IEnumerator Zoom(Vector3 from, Vector3 to, float duration)
{
    float time = 0;
    Quaternion rotation = camera.transform.rotation;
    Quaternion targetRotation = Quaternion.LookRotation(to - camera.transform.position);
    while (time < zoomDuration)
    {
        camera.transform.position = Vector3.Lerp(from, to, time / zoomDuration);
        camera.transform.rotation = Quaternion.Slerp(rotation, targetRotation, time / zoomDuration);

        time += TimeManager.instance.deltaTime;
        yield return null;
    }

    camera.transform.position = to;
    camera.transform.rotation = targetRotation;
}

This works great, but it zoom inside the object. I would like to, no matter from where and to what, I always zoom and end up at the same distance of the target.

I was thinking to use MoveTowards but inside the coroutine this will make the movement stop, but the rotation will keep going (and it's a big ugly)

So give a point A and a point B how do I calculate a distance in the middle that is set to always the same distance from B ?

Upvotes: 1

Views: 59

Answers (1)

Rehman
Rehman

Reputation: 182

For zooming to a specific distance from the target object you need to calculate the distance from the target object in direction of the camera and then subtract it to the target position.

var heading = to - from;
var dist = heading.magnitude;
var direction = heading / dist;

Vector3 newTargetPosition = to - (direction * distance);

Ref: https://docs.unity3d.com/Manual/DirectionDistanceFromOneObjectToAnother.html

With this adjustment you can stop zooming to any provided distance. Here is how adjusted code would look like:

public void ZoomIn(Vector3 target)
{
    float targetDistance = 2f;
    zoomSavePosition = camera.transform.position;
    StartCoroutine(Zoom(zoomSavePosition, target, zoomDuration, targetDistance));
}


// ZoomRoutine
IEnumerator Zoom(Vector3 from, Vector3 to, float duration, float distance)
{
    float time = 0;
    Quaternion rotation = camera.transform.rotation;
    Quaternion targetRotation = Quaternion.LookRotation(to - camera.transform.position);

    var heading = to - from;
    var dist = heading.magnitude;
    var direction = heading / dist;

    Vector3 newTargetPosition = to - (direction * distance);

    while (time < zoomDuration)
    {
        camera.transform.position = Vector3.Lerp(from, newTargetPosition, time / zoomDuration);
        camera.transform.rotation = Quaternion.Slerp(rotation, targetRotation, time / zoomDuration);

        time += Time.deltaTime;
        yield return null;
    }

    camera.transform.position = newTargetPosition;
    camera.transform.rotation = targetRotation;
}

You can set value of targetDistance where you want to stop zooming.

Upvotes: 1

Related Questions