Continuous movement script not working

Okay, I have set up a script that allows an object to move between two positions and rotations, from point A to point B, and from point B to point A. I am using an event to trigger that, but for some reason, it’s not working. Here’s my code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ChangeTransforms : MonoBehaviour
{
    //holds the object's starting position
    [SerializeField]
    private Transform sPos;
    //holds the object's finishing position
    [SerializeField]
    private Transform fPos;
    //holds the object's move speed
    [SerializeField]
    private float speed;
    //holds the object's rotation speed
    [SerializeField]
    private float rotationSpeed;

    //sets the position and rotation to the start upon starting
    private void Awake()
    {
        this.transform.SetPositionAndRotation(sPos.position, sPos.rotation);
    }

    //goes from starting position to finishing position
    public void GoToFinish()
    {
        var step = speed * Time.deltaTime;
        var rotStep = rotationSpeed * Time.deltaTime;
        this.transform.position = Vector3.MoveTowards(this.transform.position, fPos.position, step);
        this.transform.rotation = Quaternion.RotateTowards(this.transform.rotation, fPos.rotation, rotStep);
        //checks if the position of the object and its destination are approximately equal
        if(Vector3.Distance(this.transform.position, fPos.position) < 0.001f)
        {
            this.transform.position = fPos.position;
        }
    }

    //goes from finishing position to starting position
    public void GoToStart()
    {
        var step = speed * Time.deltaTime;
        var rotStep = rotationSpeed * Time.deltaTime;
        this.transform.position = Vector3.MoveTowards(this.transform.position, sPos.position, step);
        this.transform.rotation = Quaternion.RotateTowards(this.transform.rotation, sPos.rotation, rotStep);
        //checks if the position of the object and its destination are approximately equal
        if (Vector3.Distance(this.transform.position, sPos.position) < 0.001f)
        {
            this.transform.position = sPos.position;
        }
    }
}

What am I doing wrong here? What would I need to change?

The approach you have written in your GoToFinish and GoToStart methods will gradually move towards the target by no more than your step - this is what MoveTowards API does. So each time you call this method, it moves a little bit closer to the target. Therefore, you need to call this repeatedly each frame to move gradually each frame until you reach your target. I’m guessing somewhat from your description, but it’s sounds possible that you could just be calling these methods once from your event trigger.

A common approach would be to do this inside a MonoBehaviour’s Update function, as the example in the documentation does. For example, you can place your interpolation code inside the MonoBehaviour’s Update function, which is called every frame by Unity. An alternative could be to trigger a Coroutine that will repeatedly call this until it reaches the target. It depends exactly what your use-case is for which is best.

If you take the Update approach, instead of explicitly interpolating towards the start or finish transform, you can simply interpolate towards a single target transform. Your event trigger can then just change the target transform to the ‘start transform’ or the ‘finish transform’ and your object will interpolate to it. A bonus of this approach is that if you interrupt your interpolation halfway through, it will naturally begin interpolating from its current position to the new target.

Hope that helps!

1 Like

Crosspost on Unity Answers.

Why not just use a tweener package like DOTween or LeanTween?

Otherwise, if you insist on doing it in code, you can do it a lot simpler like this:

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