Search Unity

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

Discussion in 'Scripting' started by keithsoulasa, Aug 28, 2012.

  1. keithsoulasa

    keithsoulasa

    Joined:
    Feb 15, 2012
    Posts:
    2,126
    Hi all , I find myself using the following trick to stop unity from crashing when a while loop goes infinite .

    Code (csharp):
    1.  
    2.  
    3. void WhileTest() {
    4.  
    5.     int limit = 0 ;                  
    6.      a =    Random.Range(0,6);
    7.     GameObject ActiveSide = Sides[a] ;
    8.         // this is to find an inactive object , its for a custom , yet crude pooling system
    9.         while(ActiveSide.active == true limit < 20 )
    10.                     // the limit is the tick, without it if we never find an inactive object then Unity crashes
    11.             {
    12.             //  goto Restart ;
    13.     if(ActiveSide.renderer.IsVisibleFrom(Camera.main)){
    14.                
    15.                 a = Random.Range(0,6);
    16.          ActiveSide = Sides[a] ;       
    17.             limit++;
    18.                 }
    19.         limit++;       
    20.                
    21.                 //yield return new WaitForSeconds (1);
    22.             }
    23. }
    24.  
    25.  
    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 .
     
  2. imjacobf

    imjacobf

    Joined:
    Aug 3, 2012
    Posts:
    39
    If you know the amount of time you want the loop to run, use a for loop:
    Code (csharp):
    1.  
    2. void WhileTest()
    3. {
    4.     a = Random.Range(0,6);
    5.     GameObject ActiveSide = Sides[a] ;
    6.  
    7.     // this is to find an inactive object , its for a custom , yet crude pooling system
    8.     for( int i = 0; i < 20  ActiveSide.active; ++i )
    9.     {
    10.         if ( ActiveSide.renderer.IsVisibleFrom(Camera.main))
    11.         {
    12.             a = Random.Range(0, 6);
    13.             ActiveSide = Sides[a];
    14.         }
    15.     }
    16. }
    17.  
    And the syntax is:
    Code (csharp):
    1. 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.
     
    Last edited: Aug 28, 2012
  3. keithsoulasa

    keithsoulasa

    Joined:
    Feb 15, 2012
    Posts:
    2,126
    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 . ..
     
  4. imjacobf

    imjacobf

    Joined:
    Aug 3, 2012
    Posts:
    39
    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?
     
  5. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    I interpret it as a hack for dodgy/lazy coding.
     
  6. imjacobf

    imjacobf

    Joined:
    Aug 3, 2012
    Posts:
    39
    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.
     
  7. keithsoulasa

    keithsoulasa

    Joined:
    Feb 15, 2012
    Posts:
    2,126
    Actually, thanks this is alot cleaner to read

    I had to change one line of code
    Code (csharp):
    1.  
    2.  for( int i = 0; i < 20  ActiveSide.active; ++i )
    3.  
    to

    Code (csharp):
    1.  
    2.  for( int i = 0; i < 20  ActiveSide.active==true; ++i )
    3.  
     
  8. keithsoulasa

    keithsoulasa

    Joined:
    Feb 15, 2012
    Posts:
    2,126
    Here's the complete script

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class CustomPool : MonoBehaviour {
    6.     public bool OnOff ;
    7. public Transform OffPlace ;
    8. public GameObject[] Lanes ;
    9.     public Transform DefaultLoc ;
    10. public  int i ;
    11. public  int y ;
    12.     public bool OverRide ;
    13.     public bool CanSpawn ;
    14. public int a ;
    15. public int ItemMax = 10  ;
    16.     public int ItemCount ;
    17.     public GameObject Lane ;
    18.     public GameObject Side ;
    19.     //public int SideCount ;
    20. public int c ;
    21.    
    22.     public int Spawned ;
    23.     public float SideY ;
    24.     //public GameObject LaneCount ;
    25.     public GameObject[] Sides ;
    26.     public bool SideOn =true;
    27.     public bool     All=true ;
    28.     public bool  LaneOn = true ;
    29.     public float LaneY ;    
    30. //  }
    31.     void  Awake() {
    32.  
    33.     //Sides.Length = ItemCount;
    34.     //  Lanes.Length = ItemCount;
    35.         //int i ;
    36.     //int y ;
    37.     if( SideOn == true){
    38.         while(i< ItemMax){
    39.        
    40.             GameObject clone;
    41.            
    42.         clone = Instantiate(Side, OffPlace.position, OffPlace.localRotation) as GameObject;    
    43.         clone.name = "SideOff" + i ;
    44.         //clone. = "InActive" ;
    45.             //clone.active = false ;
    46.         if(OnOff == true ){
    47.                 clone.SetActiveRecursively(false) ;
    48.                 }
    49.                 Sides[i] = clone;
    50.        
    51.             i++;
    52.             }  
    53.        
    54.         }
    55.         if( LaneOn == true){
    56.         while(y< ItemMax){
    57.        
    58.             GameObject clone;
    59.            
    60.         clone = Instantiate(Lane, OffPlace.position, OffPlace.localRotation) as GameObject;    
    61.         //clone.tag = "InActive";
    62.             clone.name = "laneOff" + y ;
    63.         //clone.active = false ;
    64.         if(OnOff == true ) {
    65.                 clone.SetActiveRecursively(false);
    66.                 }
    67.                 Lanes[y] = clone ;  
    68.             //clone = Lanes[y];
    69.             y++;
    70.         }
    71.         }
    72.        
    73.        
    74.        
    75.             }
    76.     /*
    77.     void CheckOut(){
    78.             if(Spawned > (Sides.Length -4))
    79.             {
    80.         Spawned = 0 ;      
    81.             }
    82.     }*/
    83.    
    84.    
    85.    
    86.     void Start(){
    87.     //  PlaceUpSide(DefaultLoc.position);
    88.         //InvokeRepeating("CheckOut",0,1);
    89.     }
    90.    
    91.     public void GiveBackSide() {
    92.         //Spawned --;
    93.         //Spawned--;
    94.         //Spawned-- ;
    95.         print ("Spawned subtracted");
    96.        
    97.     }
    98.     public void PlaceUpLane ( Transform Me)
    99.     {
    100.     if(CanSpawn == true ){
    101.                 Spawned ++;
    102.         Restart :
    103.            
    104.             //  Spawned ++;
    105.            
    106.     int limit = 0 ;                  
    107.      c =    Random.Range(0,6);
    108.     GameObject ActiveLane = Lanes[c] ;
    109.         while(ActiveLane.active == true limit < 20 )
    110.             {
    111.             //  goto Restart ;
    112.     if(ActiveLane.renderer.IsVisibleFrom(Camera.main)){
    113.                
    114.                 c = Random.Range(0,6);
    115.          ActiveLane = Lanes[c] ;       
    116.             limit++;
    117.                 }
    118.         limit++;       
    119.                
    120.                 //yield return new WaitForSeconds (1);
    121.             }
    122.            
    123.             //  if(ActiveSide.name == "SideOn")
    124.             //{
    125.             //goto Restart ;
    126.     // if its active fallback  
    127.         //  }
    128.                
    129.     // select the game object      
    130.         //ActiveSide.active = true ;    
    131.     if(OnOff == true){
    132.         int Oni = Random.Range(0,3) ;
    133.                 DeactiveChild   Lani = ActiveLane.GetComponent<DeactiveChild>();
    134.                 ActiveLane.SetActiveRecursively(true) ;
    135.        
    136.             //Lani.Again(Oni);
    137.                 limit = 0 ;
    138.             }
    139.            
    140.             ActiveLane.transform.position = Me.position + new Vector3(0,LaneY,0 ); 
    141.     //transform.rotation
    142.     ActiveLane.transform.rotation = Me.rotation;
    143.         ActiveLane.transform.localRotation = Me.localRotation;
    144.     //ActiveSide.name = "NewSide" ;
    145.     //ActiveSide.name = "SideOn";
    146.         if(OverRide == false){ 
    147.             CanSpawn = false ;
    148.             }
    149.        
    150.         }
    151.     }
    152.    
    153.     //public void Run () {
    154.        
    155.        
    156.     //}
    157.    
    158.    
    159.    
    160.     public void PlaceUpSide ( Transform Me)
    161.     {
    162.     if(CanSpawn == true ){
    163.                 Spawned ++;
    164.         Restart :
    165.            
    166.             //  Spawned ++;
    167.            
    168.     int limit = 0 ;                  
    169.      a =    Random.Range(0,6);
    170.     GameObject ActiveSide = Sides[a] ;
    171.  for( int i = 0; i < 20  ActiveSide.active == true; ++i )
    172.  
    173.     {
    174.  
    175.         if ( ActiveSide.renderer.IsVisibleFrom(Camera.main))
    176.  
    177.         {
    178.  
    179.             a = Random.Range(0, 6);
    180.  
    181.             ActiveSide = Sides[a];
    182.  
    183.         }
    184.  
    185.     }
    186.  
    187.  
    188.            
    189.             //  if(ActiveSide.name == "SideOn")
    190.             //{
    191.             //goto Restart ;
    192.     // if its active fallback  
    193.         //  }
    194.                
    195.     // select the game object      
    196.         //ActiveSide.active = true ;    
    197.     if(OnOff == true){
    198.             ActiveSide.SetActiveRecursively(true) ;
    199.             limit = 0 ;
    200.             }
    201.            
    202.             ActiveSide.transform.position = Me.position + new Vector3(0,SideY,0 ); 
    203.     //transform.rotation
    204.     ActiveSide.transform.rotation = Me.rotation;
    205.         ActiveSide.transform.localRotation = Me.localRotation;
    206.     //ActiveSide.name = "NewSide" ;
    207.     //ActiveSide.name = "SideOn";
    208.         if(OverRide == false){ 
    209.             CanSpawn = false ;
    210.             }
    211.        
    212.         }
    213.     }
    214.     // Use this for initialization
    215.     //void Start () {
    216. }  
    217.     //}
    218.    
    219.     // Update is called once per frame
    220.     //void Update () {
    221.    
    222.     //}
    223.  
    224.  
    225.  
     
  9. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    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
     
  10. keithsoulasa

    keithsoulasa

    Joined:
    Feb 15, 2012
    Posts:
    2,126
    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 .
     
  11. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    I see. I thought the reason for your post was as a helpful tip.
     
  12. keithsoulasa

    keithsoulasa

    Joined:
    Feb 15, 2012
    Posts:
    2,126
    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 .
     
  13. imjacobf

    imjacobf

    Joined:
    Aug 3, 2012
    Posts:
    39
    Why did you have to change my code? You realize that

    Code (csharp):
    1. if ( x ) { }
    and

    Code (csharp):
    1. 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:
    Code (csharp):
    1.  
    2. for( int i = 0; i < Sides.Length; ++i )
    3.      if ( !Sides[i].renderer.IsVisibleFrom(Camera.main) )
    4.           ActiveSide = Sides[i];
    5.  
    And I suppose with this I should explain that
    Code (csharp):
    1.  if ( !x ) { }
    is exactly the same as:
    Code (csharp):
    1.  if ( x == false ) { }
     
  14. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    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'
     
  15. keithsoulasa

    keithsoulasa

    Joined:
    Feb 15, 2012
    Posts:
    2,126
    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 .
     
  16. imjacobf

    imjacobf

    Joined:
    Aug 3, 2012
    Posts:
    39
    Do the tiles scroll from the top to the bottom of the screen?
     
  17. keithsoulasa

    keithsoulasa

    Joined:
    Feb 15, 2012
    Posts:
    2,126
    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 .
     
  18. unitrade

    unitrade

    Joined:
    Aug 27, 2012
    Posts:
    20
    you can use a for loop too. i suppose you know the amount of time you need the loops to run to.