Search Unity

Bug While loop Causes Game to crash.

Discussion in 'Scripting' started by JustaDuck97, Mar 28, 2023.

  1. JustaDuck97

    JustaDuck97

    Joined:
    Jul 31, 2019
    Posts:
    45
    When the loop isn't called the game doesn't crash.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Wave_Manager : MonoBehaviour
    6. {
    7.     public int wave_Number;
    8.  
    9.     //This int is the variable the system uses to select enemies for the wave spawn. The higher the number, the more enenmies
    10.     public int wave_Budget = 10;
    11.  
    12.  
    13.     //This list references All possible enemies
    14.     [SerializeField] List<Enemy_Dictionary> master_Enemy_List = new List<Enemy_Dictionary>();
    15.     //This List is the final enemy selection for the current wave
    16.     List<GameObject> Final_Enemy_Selection = new List<GameObject>();
    17.  
    18.     private void Start()
    19.     {
    20.        select_Enemies();
    21.         Debug.Log(Final_Enemy_Selection);
    22.     }
    23.     private void select_Enemies()
    24.     {
    25.  
    26.         List<GameObject> Enemies_To_Spawn = new List<GameObject>();
    27.        
    28.         while(wave_Budget > 0)
    29.         {  
    30.             //This selects a random enemy from the master list
    31.             int random_Enemy_ID = (Random.Range(0, master_Enemy_List.Count));
    32.             //This int finds the value of the enemy
    33.             int random_Enemy_Cost = master_Enemy_List[random_Enemy_ID].enemy_Value;
    34.  
    35.             //This If statement checks to see if the system can afford the enemy.
    36.             if (random_Enemy_Cost - wave_Budget >= 0)
    37.             {
    38.                 //if it can afford it, the enemy cost is subtracted and the enemy is added to spawn list
    39.                 Enemies_To_Spawn.Add(master_Enemy_List[random_Enemy_ID].enemy_Prefab);
    40.                 random_Enemy_Cost -= wave_Budget;
    41.             }
    42.             else if (wave_Budget <= 0)
    43.             {
    44.                 break;
    45.             }                
    46.            
    47.  
    48.         }
    49.  
    50.         Enemies_To_Spawn = Final_Enemy_Selection;
    51.         Enemies_To_Spawn.Clear();
    52.  
    53.  
    54.     }
    55.  
    56.  
    57.  
    58.  
    59.  
    60.  
    61. }
    62.  
    63.  
    64.  
    65.  
    66.  
    67.     [System.Serializable]
    68.     public class Enemy_Dictionary
    69.     //This class store Enemy Data
    70.    {
    71.     public string enemy_Name;
    72.     public GameObject enemy_Prefab;
    73.     public int enemy_Value;
    74.    }
     
  2. Nefisto

    Nefisto

    Joined:
    Sep 17, 2014
    Posts:
    335
    You never change the loop condition value, this means that u will keep into the loop indefinitely, and this is causing the crash, just create some logic to change the wave_budget value and u will be good to go =D

    Also, u market ur question as bug, what was the behavior that u expect from this code?
     
    Bunny83 likes this.
  3. Magiichan

    Magiichan

    Joined:
    Jan 5, 2014
    Posts:
    403
    If wave_budget is changed upon the input of the user, then you shouldn't do this logic in a while loop.
    The game engine waits for the white loop to finish before rendering the next frame.

    One solution would be to make it a couroutine & adding a yield inside.

    But before actually going for a solution I think you need to elaborate what exactly you're trying to do here.
     
  4. JustaDuck97

    JustaDuck97

    Joined:
    Jul 31, 2019
    Posts:
    45
    The value isn't changed by the player. It increases based on the wave number. My intention is for this script to generate a list (Final_Enemy_selection) to later spawn. The budget value is a limiting amount, that progressively increases based on the wave number. So, giving me a bigger list of randomly selected enemies based on wave progress. I believe I used the Bug tag wrongly, I apologize.
     
  5. JustaDuck97

    JustaDuck97

    Joined:
    Jul 31, 2019
    Posts:
    45
    My intention is for this script to generate a list (Final_Enemy_selection) to later spawn. The budget value is a limiting amount, that progressively increases based on the wave number. So, giving me a bigger list of randomly selected enemies based on wave progress. I believe I used the Bug tag wrongly, I apologize.
     
  6. Nefisto

    Nefisto

    Joined:
    Sep 17, 2014
    Posts:
    335
    As we said, you need to reduce the wave_budget after each selection, otherwise u will be locked inside this loop forever, just keep in mind that you all your code need to run each frame, so this will keep blocking u from go forward.

    I'm almost sure that u just changed the order of a subtraction in line 40, you wrote
    random_Enemy_Cost -= wave_Budget;

    but what u really wish is
    wave_Budget -= random_Enemy_Cost;
     
    Magiichan likes this.
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,751
    Unity will lock up 100% of the time EVERY millisecond your scripting code is running.

    Nothing will render, no input will be processed, no Debug.Log() will come out, no GameObjects or transforms will appear to update.

    Absolutely NOTHING will happen... until your code either:

    - returns from whatever function it is running

    - yields from whatever coroutine it is running

    As long as your code is looping, Unity isn't going to do even a single frame of change. Nothing.

    No exceptions.

    "Yield early, yield often, yield like your game depends on it... it does!" - Kurt Dekker
     
  8. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,998
    Two things. One: infinite loops in your code will completely lock up Unity. Ideally we'd should see the Play screen frozen and be able to click STOP, but all of Unity freezes instead and we need to abort it from the control panel. That's normal (for Unity, not for other programs) and not fixable. One learns to Save before testing tricky loops and hand-checking them extra carefully.

    Two: with any weird loop like that you've got to be extra careful that wave_Budget will definitely hit 0, or that something will always break the loop, no matter what. As Nefisto wrote, it looks like you messed-up subtracting. BUT, what if wave_Budget is 3 and the cheapest enemy costs 4? This will spin forever.

    A cheap hack is to add a "go at most 100 times" counter:
    Code (CSharp):
    1. int notForever=0;
    2. while(wave_Budget>0 && notForever++<99) {
    3.  
    4. }
    5. if(notForever>=99) { // oops!
    Putting a ++ in there is extremely sleazy, but it's the best way to be 100% sure notForever increases each time.
     
    Bunny83 and Kurt-Dekker like this.