The way I implemented this is as follows:
- 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)
- 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.