Finding a right spot to put an acceleration over time Script

I’ve been given a task to remove an old outdated script, the purpose of these particular lines of code made it so that when the player double clicked a point on the map in game, the camera would move to that spot in the same amount of time no matter the distance, Eg. If it’s 3 seconds long then clicking closer to the player the camera would move much slower as opposed to moving much faster the farther away you are. The issue I’m having is that I’m crashing when it comes to figuring out how to do this and where to the new lines of code without the use of the old iTween tools.

using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
using System.Runtime.InteropServices;
using UnityEngine.UI;

/*
*    This controls the camera navigation, either by using raycasts
*    or by enabling on-screen buttons as in Google Earth
*/

public class WebPlayerControlWebGL : MonoBehaviour
{
    [DllImport("__Internal")]
    public static extern void OpenFullscreen();

    [DllImport("__Internal")]
    public static extern void CloseFullscreen();

    private GameObject GUICanvas;
    private bool colliding = false;
    private Vector3 destination;
    private int terrainLayer;// this is the layer for the terrain
    private int buildingLayer;
    private int sphereLayer;
    private bool moving = false;
    public GameObject arrowPrefab;
    public GameObject circlePrefab;
    public Transform buildingMain;
    public Transform Building;
    private float doubleClickTimeLimit = 0.25f;
    public Vector3 ArrowOrigin;
    public Vector3 ArrowTarget;
    public float moveSpeed;
    public Sprite fullScreenOn;
    public Sprite fullScreenOff;
    string lasthit;
    float clickctr = 0;

    float t;
    Vector3 startPosition;
    Vector3 target;
    float timeToReachTarget;
    /// <summary>
    /// The maximum height that the camera can go when at a clicked point
    /// </summary>
    public float maxHeight = 100f;
    public float minHeight = 0.0f;

    private Vector3 dragOrigin;
    public float dragSpeed = 2;
    public static bool sliding = false;

    private float elevationValue;
    public bool moveU = false;
    public bool moveD = false;
    //User can click on the terrain or buildings to move to that point instead of controls

    public float mouseSensitivity = 255;
    public bool ClickedAgain;
    public bool ClickedAgain2;
    public bool displayControls = true;
    public static bool inTransit = false;
    // nested GUI buttons don't render, so this will allow navigation controls to be activated   
    /// <summary>
    ///     The windowposition for displaying the measured distance.
    /// </summary>
    private Vector3 clickedPosition = new Vector3(0, 0, 0);
    bool isFullScreenNow = false;
    int defScreenWidth;
    int defScreenHeight;
    public GameObject IntroText;
    public GameObject bounaryCollisionFocusReset;
    string focusObject;
    Camera fpc;
    public bool invertCameraRotation;
    public GameObject FullScreenButton;
    public bool increaseFOV = false;
    GameObject arrow;
    // borrowed from the cameracontrolClon script
    public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 }

    public RotationAxes axes = RotationAxes.MouseXAndY;
    private void Awake()
    {
        focusObject = bounaryCollisionFocusReset.name;

        switch (Application.platform)
        {
            case RuntimePlatform.WindowsEditor: isFullScreenNow = false; break;
            case RuntimePlatform.WebGLPlayer: isFullScreenNow = Screen.fullScreen; break;
        }

        defScreenWidth = Screen.width;
        defScreenHeight = Screen.height;
    }


    // this is for initialising
    private void Start()
    {
        fpc = gameObject.GetComponentInChildren<Camera>();

        Globalvars.lockcamera = false;
        ClickedAgain = false;
        ClickedAgain2 = false;
        terrainLayer = 1 << LayerMask.NameToLayer("Terrain");// gets the number of the terrain layer and shifts it bitwise
        buildingLayer = 1 << LayerMask.NameToLayer("Buildings");
        sphereLayer = 1 << LayerMask.NameToLayer("SphereLayer");
        displayControls = true;
        GUICanvas = GameObject.Find("NewGUIControls");
        startPosition = target = transform.position;
    }


    private void DoubleClick()
    {
        OnDoubleClick();
    }

    void OnDoubleClick()
    {
        if (!Globalvars.OverButton && !Globalvars.animstart && !Globalvars.ButtonOnTour)
        {
            LayerMask layer = buildingLayer | terrainLayer;
            Ray navRay; RaycastHit rayHit;
            if (!EventSystem.current.IsPointerOverGameObject() && GUIUtility.hotControl == 0 && !moving)

            {
                navRay = Camera.main.ScreenPointToRay(Input.mousePosition);
                // check to see what the ray has hit:                   
                if (Physics.Raycast(navRay, out rayHit, Mathf.Infinity, layer))
                {
                    Globalvars.lockcamera = true;
                    displayControls = false;
                    ClickedAgain2 = false;
                    destination = rayHit.point;
                    arrow = Instantiate(arrowPrefab, new Vector3(destination.x, destination.y + 0.5f, destination.z), Quaternion.identity);
                    Vector3 travel2 = new Vector3(destination.x, destination.y + 1.8f, destination.z);
                    destination = travel2;
                    //iTween.MoveTo (firstPerson.gameObject, iTween.Hash("position", travel2,"time", 3.0f, "easeType",iTween.EaseType.linear));
                    GetComponent<CapsuleCollider>().enabled = false;
                    StartCoroutine(TurnOnCollider());
                    clickedPosition = destination;
                    destination = target;
                    inTransit = true;
                    lasthit = "terrain";
                    gameObject.transform.LookAt(arrow.transform.position);
                }
                else if (Physics.Raycast(navRay, out rayHit, Mathf.Infinity, sphereLayer) && !Globalvars.ButtonOnTour)
                {
                    Globalvars.lockcamera = true;
                    displayControls = false;
                    // start moving
                    destination = rayHit.point;
                    // add a 3D arrow at destination
                    Instantiate(circlePrefab, destination, this.transform.localRotation);
                    Vector3 travel3 = new Vector3(destination.x - 5.0f, rayHit.point.y - 5.0f, destination.z - 5.0f);
                    destination = travel3;
                    //iTween.MoveTo(firstPerson.gameObject, iTween.Hash("position", travel3,"time",3.0f, "easeType",iTween.EaseType.linear));

                    inTransit = true;
                    GetComponent<CapsuleCollider>().enabled = false;
                    StartCoroutine(TurnOnCollider());
                    ClickedAgain = false;
                    clickedPosition = destination;
                    lasthit = "BoundarySphere";
                }
            }
        }
    }

    public IEnumerator TurnOnCollider()
    {
        yield return new WaitForSeconds(2.8f);
        GetComponent<CapsuleCollider>().enabled = true;
    }
    // called once a frame
    void doubleClickCheck()//double click
    {
        if (Input.GetMouseButtonDown(0))
        { clickctr += .3f; }
        if (clickctr > .3f) { OnDoubleClick(); clickctr = 0; }
        if (clickctr > 0) { clickctr -= Time.deltaTime; }
        else { clickctr = 0; }
    }




    private void Update()
    {
        IncreaseFOVOnMove();
        doubleClickCheck();

        t += Time.deltaTime / timeToReachTarget;
        transform.position = Vector3.Lerp(startPosition, target, t);

        //print(Vector3.Distance(gameObject.transform.position, bs));
        if (displayControls == true)
        {
            //moving = false;
            GUICanvas.SetActive(true);
            if (moveU)
            {
                if (gameObject.transform.position.y < maxHeight) { gameObject.transform.position += gameObject.transform.up * moveSpeed * Time.deltaTime; }
            }
            else
            {
                if (moveD) { if (gameObject.transform.position.y > minHeight) { gameObject.transform.position -= gameObject.transform.up * moveSpeed * Time.deltaTime; } }
                else { gameObject.transform.position = gameObject.transform.position; }
            }
        }
        else
        { GUICanvas.SetActive(false); }

        if (Vector3.Distance(gameObject.transform.transform.position, destination) < 1f) //move until within a meter of the destination
        {
            inTransit = false;
            Globalvars.lockcamera = false;
            displayControls = true;
            if (IntroText.activeSelf) { IntroText.SetActive(false); }
            Destroy(arrow);
        }

        if (inTransit && lasthit == "terrain") { gameObject.transform.position = Vector3.MoveTowards(gameObject.transform.position, destination, 25 * Time.deltaTime * moveSpeed); }
        if (inTransit && lasthit == "BoundarySphere")
        {


            Vector3 direction = bounaryCollisionFocusReset.transform.position - gameObject.transform.position;
            Vector3 dirFromAtoB = (bounaryCollisionFocusReset.transform.position - gameObject.transform.position).normalized;
            float dotProd = Vector3.Dot(dirFromAtoB, gameObject.transform.forward);

            if (dotProd < 0.99995)
            {
                Vector3 newDirection = Vector3.RotateTowards(transform.forward, direction, Time.deltaTime, 0); //.LookAt(target[targetIndex]);
                gameObject.transform.rotation = Quaternion.LookRotation(newDirection);
            }
            else
            {
                gameObject.transform.LookAt(bounaryCollisionFocusReset.transform);
            }
            gameObject.transform.position = Vector3.MoveTowards(gameObject.transform.position, destination, 50 * Time.deltaTime * moveSpeed);

        }

        if (Vector3.Distance(gameObject.transform.position, destination) < 1f) { inTransit = false; }
        if (lasthit == "terrain" && !inTransit) { resetCameraRotation(); }//{firstPerson.transform.Rotate(-firstPerson.transform.eulerAngles.x,0, -firstPerson.transform.eulerAngles.z, Space.World); lasthit = null; }


        if (gameObject.transform.position.y > minHeight && elevationValue < 0)
        { gameObject.transform.Translate(Vector3.up * elevationValue, Space.World); }
        if (gameObject.transform.position.y < maxHeight && elevationValue > 0)
        { gameObject.transform.Translate(Vector3.up * elevationValue, Space.World); }
        if (Input.GetMouseButtonDown(0) && GUIUtility.hotControl == 0 && !EventSystem.current.IsPointerOverGameObject())
        { dragOrigin = Input.mousePosition; return; }
        if (!Input.GetMouseButton(0)) { return; }

        if (GUIUtility.hotControl == 0 && !EventSystem.current.IsPointerOverGameObject())
        {
            Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - dragOrigin);

            if (invertCameraRotation)
            {
                if (!sliding)
                { gameObject.transform.localEulerAngles -= new Vector3(mouseSensitivity * Time.deltaTime * -pos.y, -mouseSensitivity * Time.deltaTime * -pos.x, 0); }
            }
            else { if (!sliding) { gameObject.transform.localEulerAngles -= new Vector3(mouseSensitivity * Time.deltaTime * pos.y, -mouseSensitivity * Time.deltaTime * pos.x, 0); } }

        }
        // these will adjust the camera's altitude (i.e. height in world space)
        if (Input.GetKey(KeyCode.PageUp))
        { gameObject.transform.Translate(Vector3.up * moveSpeed, Space.World); }
        if (Input.GetKey(KeyCode.PageDown))
        { gameObject.transform.Translate(Vector3.up * -moveSpeed, Space.World); }

    }
    //Values for function are set by the slider

    public void SetDestination(Vector3 destination, float time)
    {
        t = 0;
        startPosition = transform.position;
        timeToReachTarget = time;
        target = destination;
        time = 3f;
    }

    void resetCameraRotation()
    {
        if (gameObject.transform.eulerAngles.x == 0) { lasthit = null; }
        gameObject.transform.transform.rotation = Quaternion.RotateTowards(gameObject.transform.rotation, Quaternion.Euler(0, gameObject.transform.eulerAngles.y, 0), 100 * Time.deltaTime);
    }

    public void ElevationSlider(float sliderValue)
    {
        if (sliderValue != 0)
        {
            sliding = true; //sliding bool is to stop camera rotation when sliding
            if (GameObject.Find("elevationInstruction") != null) { GameObject.Find("elevationInstruction").SetActive(false); }
        }
        else { sliding = false; }


        elevationValue = sliderValue;
    }

    public void moveUp()
    {
        if (moveU)
            moveU = false;
        else
            moveU = true;
    }
    public void moveDown()
    {
        if (moveD)
            moveD = false;
        else
            moveD = true;
    }

    void OnCollisionEnter(Collision coll)
    {
        float force = 800.0f;
        if (coll.gameObject.layer == LayerMask.NameToLayer("Buildings"))
        {

            Globalvars.lockcamera = false;
            colliding = true;
            displayControls = true;
            Vector3 dir = coll.contacts[0].point - transform.position;
            // We then get the opposite (-Vector3) and normalize it
            dir = -dir.normalized;
            // And finally we add force in the direction of dir and multiply it by force.
            // This will push back the player
            GetComponent<Rigidbody>().AddForce(dir * force);
            inTransit = false;
        }
        if (coll.gameObject.layer == LayerMask.NameToLayer("Terrain"))
        {

            Globalvars.lockcamera = false;
            colliding = true;
            displayControls = true;
            inTransit = false;
            Vector3 dir = coll.contacts[0].point - transform.position;
            // We then get the opposite (-Vector3) and normalize it
            dir = -dir.normalized;
            // And finally we add force in the direction of dir and multiply it by force.
            // This will push back the player
            GetComponent<Rigidbody>().AddForce(dir * force);

        }
        if (coll.gameObject.layer == LayerMask.NameToLayer("placedObject")) { inTransit = false; }

    }

    void IncreaseFOVOnMove()
    {
        if (increaseFOV)
        {
            if (inTransit && fpc.fieldOfView < 80 && lasthit != "BoundarySphere")
            { fpc.fieldOfView += Time.deltaTime * 30; }
            else if (fpc.fieldOfView > 65 && lasthit == "BoundarySphere" || fpc.fieldOfView > 65 && !inTransit) { fpc.fieldOfView -= Time.deltaTime * 60; }
        }
    }

    void OnCollisionExit(Collision coll)
    { colliding = false; }

    public void GoFullScreen()
    {
        if (!isFullScreenNow)
        {
            Screen.fullScreen = true;
            isFullScreenNow = true;
            FullScreenButton.GetComponent<Image>().sprite = fullScreenOff;
        }
        else
        {
            FullScreenButton.GetComponent<Image>().sprite = fullScreenOn;
            Screen.fullScreen = false;
            isFullScreenNow = false;
        }
    }

    public bool IsFullScreen()
    {
        return Application.platform == RuntimePlatform.WebGLPlayer ? Screen.fullScreen : isFullScreenNow;
    }
}

That is a STAGGERING amount of code to do what you say. What’s with the buildings and the rigidbody stuff???

Most likely you will need to figure out all the magic the above code does and then replicate it, but do so one feature at a time.

Camera stuff is pretty tricky… you may wish to consider using Cinemachine from the Unity Package Manager.

For moving any quantity (such as a position) smoothly over time, I always do this process:

Smoothing movement between any two particular values:

You have currentQuantity and desiredQuantity.

  • only set desiredQuantity
  • the code always moves currentQuantity towards desiredQuantity
  • read currentQuantity for the smoothed value

Works for floats, Vectors, Colors, Quaternions, anything continuous or lerp-able.

The code: SmoothMovement.cs · GitHub