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;
}