To clarify my comment, there are two main issues. The first being that movement should not be done outside of Update
, a Coroutine
, or any other equivalent. The reason for this is because normal functions are called and ran until completed. Update
and Coroutines
run in small increments over time, which is generally how movement should be done. With your current setup, the movement would all happen in one frame.
The second issue is your comparison. As a Vector2
is just two floats, there is a chance of floating point values never quit being equal
. To fix this problem, instead of a direct comparison, you can compare the distance between two Vector2
values to a value close enough to 0, or what is called an epsilon value. In doing this, you assure that the value is close enough and can terminate your loop.
Combining all of this into an answer, I would advise you to use a Coroutine
as it is similar to your current setup, just tweaked slightly to assure the movement happens over multiple frames. I would also recommend using Vector2.MoveTowards
over the current MovePosition
as MovePosition is generally placed in FixedUpdate
as it is a physics-based function.
[SerializeField] private Vector2[] path;
[SerializeField] private float moveSpeed;
private Coroutine movePath = null;
private void Start()
{
movePath = StartCoroutine(TraversePath(path));
}
private IEnumerator TraversePath(Vector2[] p)
{
int pathIdx = 0;
while (pathIdx < p.Length)
{
yield return StartCoroutine(MoveToTarget(p[pathIdx]));
pathIdx++;
}
movePath = null;
}
private IEnumerator MoveToTarget(Vector2 target)
{
while (!Mathf.Approximately(Vector2.Distance(target, transform.position), 0.0f))
{
transform.position = Vector2.MoveTowards(transform.position, target, moveSpeed * Time.deltaTime);
yield return null;
}
transform.position = target;
}