Check if a set of objects is moving

Hi,

I’m trying to define a function that will check if a certain set of objects is moving. The problem is that Unity will crash on me during the execution of this code. Not sure if I’m doing something wrong in the code or perhaps there is an easier method than what I’m trying to use. The function is called when a certain type of object is destroyed if that makes a difference

bool partsAreMoving = true;
while(partsAreMoving)
{
  Debug.Log("Loop Start");
  partsAreMoving = false;
  GameObject[] machineParts = GameObject.FindGameObjectsWithTag("MachinePart");
  foreach(GameObject part in machineParts)
  {
    if(part.rigidbody == null)
      continue;
    if(part.rigidbody.velocity.magnitude > 0) //i.e. moving
    {
      Debug.Log("Moving " + part.rigidbody.velocity.magnitude);
      partsAreMoving = true; //Crashes if I don't comment this out
    }
    else
    {
      Debug.Log("Not moving");
    }
  }
  Debug.Log("Loop end");
}

This will crash Unity when it hits it (I won’t even get the “Loop Start” in the log) but if I comment out the line that sets partsAreMoving to true in the foreach loop it will work fine. What am I doing wrong? Is this too intense a calculation?

Thanks in advance

  1. You should do the FindGameObjectsWithTag outside of the loop as it is an expensive call. If these things create/destroy you may want to manage a list of them, but in any case

  2. You set partsAreMoving to true and you loop on that fact. So if anything is moving, this loop will never exit, what looks like a crash is an infinite loop. You might want to yield or something, but I think it would be better to use Update to scan the list once and move on.

  3. For good measure, part.rigidbody.velocity.magnitude > 0.0 or 0f to make sure it’s not using integer math

Using the stuff that DaveA suggested I’ve got this working now using the following (excluding the managed list, haven’t done that yet)

bool checkMachine = false;

public void reset()
{
  GoToMachine();
  checkMachine = true;
}

private void LateUpdate()
{
  ...

  if(checkMachine)
    CheckIfPartsAreMoving();
}

private void CheckIfPartsAreMoving()
{
  bool moving = false;
  GameObject[] machineParts = GameObject.FindGameObjectsWithTag("MachinePart");
  foreach(GameObject part in machineParts)
  {
    if(part.rigidbody == null)
      continue;
    if(part.rigidbody.velocity.magnitude > .01f)
      moving = true;
  }

  if(!moving)
    GoToStart();
}