Using a limiting number with While Loops, good or bad idea

Hi all , I find myself using the following trick to stop unity from crashing when a while loop goes infinite .

void WhileTest() {

	int limit = 0 ; 				 
	 a = 	Random.Range(0,6);
	GameObject ActiveSide = Sides[a] ;
        // this is to find an inactive object , its for a custom , yet crude pooling system 
		while(ActiveSide.active == true limit < 20 )
                    // the limit is the tick, without it if we never find an inactive object then Unity crashes 
			{
			//	goto Restart ; 
	if(ActiveSide.renderer.IsVisibleFrom(Camera.main)){	
				
				a = Random.Range(0,6);
		 ActiveSide = Sides[a] ;		
			limit++; 
				}
		limit++; 		
				
				//yield return new WaitForSeconds (1);
			}
}

Of course any while loop crashes could be avoided if I could write perfect code that always finds what its looking for .
But what I do is here is create a int , limit , thats increased each time the while loop is ran , this way if for some bizarre reason we cant find an inactive object we don’t crash .

If you know the amount of time you want the loop to run, use a for loop:

void WhileTest() 
{
	a = Random.Range(0,6);
	GameObject ActiveSide = Sides[a] ;

    // this is to find an inactive object , its for a custom , yet crude pooling system 
	for( int i = 0; i < 20  ActiveSide.active; ++i )
	{
		if ( ActiveSide.renderer.IsVisibleFrom(Camera.main))
		{
			a = Random.Range(0, 6);
			ActiveSide = Sides[a];
		}
	}
}

And the syntax is:

for( int i = 0; i < 20; ++i )

You have for( variable initialization (these are only available in the for loop); terminating conditions; what to perform after each loop (used usually to increment the variables you made in the initialization)).

You can always take some cracks at using them and if you run into issues just post here and I’ll help you out.

What I basically do here is check to see if the object I selected is active or not , if it isn’t active the loop ends and we just select that object .

If it is active , we keep the loop going .
The problem is sometimes all the objects are active, so I need to put a limit to how many times we run the loop .
So i don’t really know how many times we’re going to run the loop until i run it . …

What exactly are you trying to do with the loop? Why don’t you just iterate through the Sides[ ] and check if the objects are active or not?

I interpret it as a hack for dodgy/lazy coding.

That’s possible. Looking at his code it isn’t doing anything. It would be just as effective to not have the function at all.

Actually, thanks this is alot cleaner to read

I had to change one line of code

 for( int i = 0; i < 20  ActiveSide.active; ++i )

to

 for( int i = 0; i < 20  ActiveSide.active==true; ++i )

Here’s the complete script

using UnityEngine;
using System.Collections;

public class CustomPool : MonoBehaviour {
	public bool OnOff ; 
public Transform OffPlace ; 
public GameObject[] Lanes ;
	public Transform DefaultLoc ;
public	int i ; 
public	int y ;
	public bool OverRide ; 
	public bool CanSpawn ; 
public int a ; 
public int ItemMax = 10  ;
	public int ItemCount ; 
	public GameObject Lane ; 
	public GameObject Side ; 
	//public int SideCount ;
public int c ; 
	
	public int Spawned ;
	public float SideY ; 
	//public GameObject LaneCount ;
	public GameObject[] Sides ;
	public bool SideOn =true; 
	public bool 	All=true ;
	public bool  LaneOn = true ; 
	public float LaneY ; 	
//	}
	void  Awake() {

	//Sides.Length = ItemCount;
	//	Lanes.Length = ItemCount;
		//int i ; 
	//int y ; 
	if( SideOn == true){
		while(i< ItemMax){ 
		
			GameObject clone;
            
		clone = Instantiate(Side, OffPlace.position, OffPlace.localRotation) as GameObject;		
		clone.name = "SideOff" + i ;
		//clone. = "InActive" ;
			//clone.active = false ;
		if(OnOff == true ){
				clone.SetActiveRecursively(false) ;
				}
				Sides[i] = clone;
		
			i++; 
			}	
		
		}
		if( LaneOn == true){
		while(y< ItemMax){ 
		
			GameObject clone;
            
		clone = Instantiate(Lane, OffPlace.position, OffPlace.localRotation) as GameObject;		
		//clone.tag = "InActive"; 
			clone.name = "laneOff" + y ;
		//clone.active = false ; 
		if(OnOff == true ) {
				clone.SetActiveRecursively(false); 
				}
				Lanes[y] = clone ; 	
			//clone = Lanes[y];	
			y++;
		}
		}
		
		
		
			}
	/*
	void CheckOut(){
			if(Spawned > (Sides.Length -4))
			{
		Spawned = 0 ; 		
			}
	}*/
	
	
	
	void Start(){
	//	PlaceUpSide(DefaultLoc.position);
		//InvokeRepeating("CheckOut",0,1);
	}
	
	public void GiveBackSide() {
		//Spawned --;
		//Spawned--;
		//Spawned-- ;
		print ("Spawned subtracted");
		
	}
	public void PlaceUpLane ( Transform Me)
	{
	if(CanSpawn == true ){
				Spawned ++;	
		Restart :
			
			//	Spawned ++;
			
	int limit = 0 ; 				 
	 c = 	Random.Range(0,6);
	GameObject ActiveLane = Lanes[c] ;
		while(ActiveLane.active == true limit < 20 )
			{
			//	goto Restart ; 
	if(ActiveLane.renderer.IsVisibleFrom(Camera.main)){	
				
				c = Random.Range(0,6);
		 ActiveLane = Lanes[c] ;		
			limit++; 
				}
		limit++; 		
				
				//yield return new WaitForSeconds (1);
			}
			
			//	if(ActiveSide.name == "SideOn")
			//{
			//goto Restart ;
	// if its active fallback	
		//	}
				
	// select the game object		
		//ActiveSide.active = true ; 	
	if(OnOff == true){
		int Oni = Random.Range(0,3) ; 
				DeactiveChild	Lani = ActiveLane.GetComponent<DeactiveChild>();
				ActiveLane.SetActiveRecursively(true) ;
		
			//Lani.Again(Oni);
				limit = 0 ; 
			}
			
			ActiveLane.transform.position = Me.position + new Vector3(0,LaneY,0 );	
	//transform.rotation
	ActiveLane.transform.rotation = Me.rotation;
		ActiveLane.transform.localRotation = Me.localRotation; 
	//ActiveSide.name = "NewSide" ; 
	//ActiveSide.name = "SideOn";
		if(OverRide == false){	
			CanSpawn = false ; 
			}
		
		}
	}
	
	//public void Run () {
		
		
	//}
	
	
	
	public void PlaceUpSide ( Transform Me)
	{
	if(CanSpawn == true ){
				Spawned ++;	
		Restart :
			
			//	Spawned ++;
			
	int limit = 0 ; 				 
	 a = 	Random.Range(0,6);
	GameObject ActiveSide = Sides[a] ;
 for( int i = 0; i < 20  ActiveSide.active == true; ++i )

    {

        if ( ActiveSide.renderer.IsVisibleFrom(Camera.main))

        {

            a = Random.Range(0, 6);

            ActiveSide = Sides[a];

        }

    }


			
			//	if(ActiveSide.name == "SideOn")
			//{
			//goto Restart ;
	// if its active fallback	
		//	}
				
	// select the game object		
		//ActiveSide.active = true ; 	
	if(OnOff == true){
			ActiveSide.SetActiveRecursively(true) ;
			limit = 0 ; 
			}
			
			ActiveSide.transform.position = Me.position + new Vector3(0,SideY,0 );	
	//transform.rotation
	ActiveSide.transform.rotation = Me.rotation;
		ActiveSide.transform.localRotation = Me.localRotation; 
	//ActiveSide.name = "NewSide" ; 
	//ActiveSide.name = "SideOn";
		if(OverRide == false){	
			CanSpawn = false ; 
			}
		
		}
	}
	// Use this for initialization
	//void Start () {
}	
	//}
	
	// Update is called once per frame
	//void Update () {
	
	//}

I mean putting a limiter into a while loop.

Sure it might save your ass, but it generally should not be needed, hence my comment

This is my first attempt at writing my own pool system for my procedural generated game ,

I posted a small part of the script to get feed back on how to kill a while loop when the condition will never be fulfilled .

I see. I thought the reason for your post was as a helpful tip.

Don’t get me wrong, if all goes well I should never need it , but its a good thing to keep around so instead of the game crashing, the loop terminates .

Why did you have to change my code? You realize that

if ( x ) { }

and

if ( x == true ) { }

are exactly the same, right?

Also, if I understand your code correctly, then you are iterating through to try and find the first object that isn’t visible from the main camera? You can do something like this:

for( int i = 0; i < Sides.Length; ++i )
     if ( !Sides[i].renderer.IsVisibleFrom(Camera.main) )
          ActiveSide = Sides[i];

And I suppose with this I should explain that

 if ( !x ) { }

is exactly the same as:

 if ( x == false ) { }

Absolutely, and I’ve done the same thing myself in the past.

I generally prefer an event driven system rather than a ‘run this until this happens system’

Actually I didn’t know that , i’m still new with C#, thanks for the tips .

My game is a little procedural generated avoid objects game , so after we don’t see a gameobject anymore I set it back to inactive , then place in forward in the track .
I already had this working with Intestate and destroy, but since that’s a performance nightmare on android I’m writing this code to reuse the road pieces .

Do the tiles scroll from the top to the bottom of the screen?

Not exactly, I’m actually moving the camera and the ship up , and when a object is far enough from the ship , I run a script on it to call the PlaceUpSide method . and create a new object with the same position, aside from an extra Y .

you can use a for loop too. i suppose you know the amount of time you need the loops to run to.