While Loop not Breaking

Hi. I’m trying to make it so that a moving ship’s path can be intersected while travelling by clicking a second time. However, even though I break the while loop moving it and it prints that the loop broke and finished, it doesn’t actually stop the loop until the while loop’s parameters are false. Please help, and thanks.

using System.Collections;//Jump to line 49 and below if you want to see where the problem is.
using System.Collections.Generic;
using UnityEngine;

public class Select : MonoBehaviour
{
    public GameObject selectorPrefab;
    public float moveSpeed;

    private GameObject selectedObject;
    private GameObject clone;
    private float jumpDistance;
    private int currentDirectionChangeNumber = 0;
    private int previousDirectionChangeNumber = 1;

    void Update()
    {
        jumpDistance = moveSpeed * Time.deltaTime;

        if(Input.GetMouseButtonDown(0))//left click
        {
            RaycastHit hit;
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            if(Physics.Raycast(ray, out hit))
            {
                if(hit.collider.tag == "Ship" && selectedObject != hit.transform.gameObject)
                {
                    Destroy(clone);

                    Vector3 position = hit.transform.position;
                    float scaleMultiplier = (hit.transform.localScale.x + hit.transform.localScale.z) / 2;

                    selectedObject = hit.transform.gameObject;

                    clone = Instantiate(selectorPrefab);
                    clone.transform.position = position;
                    clone.transform.localScale *= scaleMultiplier;
                    clone.transform.parent = selectedObject.transform;
                }
                else if(hit.collider.tag != "Ship")
                {
                    Destroy(clone);

                    selectedObject = hit.transform.gameObject;
                }
            }
        }
        else if(Input.GetMouseButtonDown(1))//right click, this is where the important stuff is
        {
            RaycastHit hit;
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            if(Physics.Raycast(ray, out hit) && hit.collider.name == "Baseplate" && selectedObject.transform.tag == "Ship")
            {
                Debug.Log("Changing targets");
                currentDirectionChangeNumber++;
                Debug.Log(currentDirectionChangeNumber + " is current, " + previousDirectionChangeNumber + " is previous");
                StartCoroutine(MoveToTarget(hit.point));
                Debug.Log(hit.point + " is target");
            }
        }
    }

    IEnumerator MoveToTarget(Vector3 targetPosition)
    {
        GameObject localSelectedObject = selectedObject;

        while(localSelectedObject.transform.position != targetPosition)
        {
            if(currentDirectionChangeNumber > previousDirectionChangeNumber)
            {
                Debug.Log("Breaking");
                break;
            }

            yield return 0;

            localSelectedObject.transform.position = Vector3.MoveTowards(localSelectedObject.transform.position, targetPosition, jumpDistance);
        }
        Debug.Log("Loop finished");
        previousDirectionChangeNumber++;
    }
}

Please help.

Please

I will try to help you work through this as much as I can.
It is pretty late here and I am a bit tired… but…

It’s possible that you might want to put the direction change check in the raycast block before calling the coroutine.
What I think is that if you have the direction change comparison happen before even calling the co-routine, it will
never get called. That will also allow you to introduce a sentinel variable into the while loop that will stop it from looping.
Such as, whileLooping = false; if the currentDirectionChangeNumber > previousDirectionChangeNumber. and wrap
the while loop in a whileLooping check. Something like that?

You may want to read this thread about breaking out of loops:

Thanks, I’ll try this out. While I do, I’m still open to ideas and suggestions.

What if before you start a new coroutine stop the old one? As a side note, it is better to use CompareTag() than checking for equality.

using System.Collections;
using UnityEngine;

public class Select : MonoBehaviour
{
    public GameObject selectorPrefab;
    public float moveSpeed;

    private GameObject selectedObject;
    private GameObject clone;
    private float jumpDistance;
    private Coroutine moveToTargetCoroutine;

    void Update()
    {
        jumpDistance = moveSpeed * Time.deltaTime;

        if (Input.GetMouseButtonDown(0))//left click
        {
            RaycastHit hit;
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            if (Physics.Raycast(ray, out hit))
            {
                if (hit.collider.CompareTag("Ship") && selectedObject != hit.transform.gameObject)
                {
                    Destroy(clone);

                    Vector3 position = hit.transform.position;
                    float scaleMultiplier = (hit.transform.localScale.x + hit.transform.localScale.z) / 2;

                    selectedObject = hit.transform.gameObject;

                    clone = Instantiate(selectorPrefab);
                    clone.transform.position = position;
                    clone.transform.localScale *= scaleMultiplier;
                    clone.transform.parent = selectedObject.transform;
                }
                else if (!hit.collider.CompareTag("Ship"))
                {
                    Destroy(clone);

                    selectedObject = hit.transform.gameObject;
                }
            }
        }
        else if (Input.GetMouseButtonDown(1))//right click, this is where the important stuff is
        {
            RaycastHit hit;
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            if (Physics.Raycast(ray, out hit) && hit.collider.name == "Baseplate" && selectedObject.CompareTag("Ship"))
            {
                if (moveToTargetCoroutine != null)
                {
                    StopCoroutine(moveToTargetCoroutine);
                }
                moveToTargetCoroutine = StartCoroutine(MoveToTarget(hit.point));
            }
        }
    }

    IEnumerator MoveToTarget(Vector3 targetPosition)
    {
        GameObject localSelectedObject = selectedObject;

        while (localSelectedObject.transform.position != targetPosition)
        {
            localSelectedObject.transform.position = Vector3.MoveTowards(localSelectedObject.transform.position, targetPosition, jumpDistance);
            yield return null;
        }
    }
}

Worked, thanks Pengo! And thanks to everyone else who tried