Smooth movement between waypoints

Somewhere on one of these later videos, there was a mention of going through how to get enemies to move smoothly between tiles. I’ve had a play around trying to get it to work, but to not avail.

Any chance of covering this, or can someone who has got it working, provide a solution?

The way I implemented this is as follows:

  1. the enemies do their walkpath coroutine, and instead of teleporting directly to the next waypoint, they store their current position, the next waypoint’s position, current rotation and the desired rotation to have at the next waypoint (so it looks like they’re just not sliding but also turning towards it)
  2. In the enemies’ Update() they smoothly interpolate their position and rotation between current and destination. The interpolation is tuned so that it takes about the same time as the coroutine’s rate to reach the next point.

In code snippets, it’s more or less like this, in the coroutine:

hasTarget = true;
startPosition = transform.position;
startRotation = transform.rotation;
/* w is the destination waypoint */
targetRotation = Quaternion.LookRotation((w.transform.position - transform.position).normalized, Vector3.up);
targetPosition = w.transform.position;
/* moveStep is used to control the interpolation */
moveStep = 0.0f;

In Update():

void Update () {
    if(!hasTarget)
        return;
    /* slerp does a spherical interpolation between rotations
       moveStep * 2 means the target rotation is reached at twice the rate
       both lerp and slerp cap the step between 0.0 and 1.0 so there won't be any
       extra rotation even though it is faster than the position interpolation */
    transform.rotation = Quaternion.Slerp(startRotation, targetRotation, moveStep * 2);
    /* lerp does a linear interpolation between vectors */
    transform.position = Vector3.Lerp(startPosition, targetPosition, moveStep);
    moveStep += Time.deltaTime;
}

In situations the enemy can’t/doesn’t want to move anymore, hasTarget is set to false.

Maybe this helps some to at least get started.

2 Likes

Ah, thats interesting,thanks… I was using Vector3.MoveTowards, but it wasnt really doing what I wanted and I couldnt be sure if that was the correct method.

My gaming/dev PC is out of commission for the next week or so, so I wont get to try this for awhile, but will give it a go once it’s back up.

Thanks again for posting this :+1:

I got to this section a few days ago and wanted to add smoother movements. Not a full smooth motion but a smooth motion to each block/waypoint. I couldn’t use the code here but i ended up using a while loop. I actually struggled with this for a while so i hope someone else could use the code to help them out. There are a few things missing but i’m too tired to finish it tonight but it will carry the same principle. Rotation…target etc etc…


    private float transition = 1f;
    [SerializeField] float speed = 3f;


    // Use this for initialization
    void Start()
    {
        PathFinder pathfinder = FindObjectOfType<PathFinder>();
        var path = pathfinder.GetPath();

        StartCoroutine(FollowPath(path));
    }

    // Update is called once per frame
    void Update()
    {

    }

    IEnumerator FollowPath(List<Waypoint> path)
    {
        print("Starting patrol...");
        foreach (Waypoint waypoint in path)
        {
           // Vector3 top = new Vector3(0, 5, 0);

            while (Vector3.Distance(transform.position, waypoint.transform.position) > .02f)
            {
                
                transform.position = Vector3.Lerp(transform.position, waypoint.transform.position, transition * Time.deltaTime * speed);
                yield return null;
            }
            yield return new WaitForSeconds(1f);
            

        }
        print("Ending patrol");
    }


}

I’ll have it completely done by this week if anyone has anyone questions on it, feel free to correct anything you see wrong… GoodNight…

1 Like

Privacy & Terms