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