Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Bug If with boolean not working...

Discussion in 'Scripting' started by westergard, Mar 29, 2024.

  1. westergard

    westergard

    Joined:
    May 4, 2015
    Posts:
    100
    Hello, i'm trying to learn how to use booleans with if and else if ... It's not working as i intend.

    I have a player that can equip a sword or a torchlight, but not both at the same time. Function wells individually, but it's not working when i try to equip the sword when the torchlight is already there, the sword appears... Maybe it has to do with the order of the "else if" in the list??

    Thanks a lot for your input:

    Here is my code:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class AppearDisappear : MonoBehaviour
    4. {
    5.     public GameObject sword;
    6.     public GameObject torchLight;
    7.     bool swordEquipped;
    8.     bool torchLightEquipped;
    9.     void Start()
    10.     {
    11.         sword.SetActive(false);
    12.         torchLight.SetActive(false);
    13.         swordEquipped = false;
    14.         torchLightEquipped = false;
    15.     }
    16.  
    17.     void Update()
    18.     {
    19.         if (Input.GetKeyDown(KeyCode.Alpha1) &&!swordEquipped)
    20.         {
    21.             sword.SetActive(true);
    22.             swordEquipped = true;
    23.         }
    24.  
    25.         else if (Input.GetKeyDown(KeyCode.Alpha1) && swordEquipped)
    26.         {
    27.             sword.SetActive(false);
    28.             swordEquipped = false;
    29.         }
    30.  
    31.         else if (Input.GetKeyDown(KeyCode.Alpha1) && torchLightEquipped) // this is the first part not working
    32.         {
    33.             sword.SetActive(false);
    34.             swordEquipped = false;
    35.         }
    36.  
    37.         else if (Input.GetKeyDown(KeyCode.Alpha2) && torchLightEquipped)
    38.         {
    39.             torchLight.SetActive(false);
    40.             torchLightEquipped = false;
    41.         }
    42.  
    43.         else if (Input.GetKeyDown(KeyCode.Alpha2) && !torchLightEquipped)
    44.         {
    45.             torchLight.SetActive(true);
    46.             torchLightEquipped = true;
    47.         }
    48.  
    49.         else if (Input.GetKeyDown(KeyCode.Alpha2) && swordEquipped) // this is the second part not working
    50.         {
    51.             torchLight.SetActive(false);
    52.             torchLightEquipped = false;
    53.         }
    54.     }
    55. }
    56.  
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,589
    All "if" statements use a condition which equates to a bool. C# isn't broken so you simply need to debug your logic yourself.

    Read your input once, don't repeat then same thing multiple times and simplify your logic.

    Your logic above will only ever execute one of the code blocks. Everything is mutually exclusive.

    If you want to be able to do both in a single update then line 31 should be a new "if" not "else if" which is obviously a continuation of the previous checks.
     
  3. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,589
    Look at your code, if you press alpha1, it'll only ever get to the first two blocks as one of them will be true.
     
    Bunny83 likes this.
  4. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,933
    You have three possible states then:
    - Equipping nothing
    - Equipping sword
    - Equipping torch

    Two bools is a bad way to represent these three states. Two bools has 4 possible states:
    - Equipping neither sword nor torch
    - Equipping BOTH sword and torch
    - Equipping sword and not torch
    - Equipping torch and not sword.

    This problem will only get worse as you add more and more items to this list.

    A much better way to represent your system is with an enum, which can have 3 (or as many as you'd like) states. For example:

    Code (CSharp):
    1. enum ItemType {
    2.   None,
    3.   Sword,
    4.   Torch
    5. }
    6.  
    7. public ItemType CurrentlyEquippedItem;
     
    Last edited: Mar 29, 2024
  5. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    1,054
    You don't need to track the equipped states of your items with an additional bool. The fact that an item's game object is active will tell you that it's equipped.

    Here's a slightly easier way to do your thing:
    Code (CSharp):
    1. using UnityEngine;
    2. public class AppearDisappear : MonoBehaviour
    3. {
    4.     public GameObject sword;
    5.     public GameObject torchLight;
    6.  
    7.     void Update()
    8.     {
    9.         if (Input.GetKeyDown(KeyCode.Alpha1))
    10.         {
    11.             sword.SetActive(!sword.activeSelf); // toggle sword on and off
    12.             torchLight.SetActive(false); // disable torch
    13.         }
    14.         else if (Input.GetKeyDown(KeyCode.Alpha2))
    15.         {
    16.             torchLight.SetActive(!torchLight.activeSelf); // toggle torch on and off
    17.             sword.SetActive(false); // disable sword
    18.         }
    19.     }
    20. }

    It'll start to get a little long as you add more items because you'll need to disable all the items that aren't selected.


    A more advanced method:
    Code (CSharp):
    1. public GameObject[] items;
    2.  
    3.     void OnGUI()
    4.     {
    5.         Event e = Event.current;
    6.         if (e.type == EventType.KeyDown)
    7.         {
    8.             int item = (int)(e.keyCode - KeyCode.Alpha0); // key to item number
    9.             if (item >= 0 && item <= 9)
    10.             {
    11.                 items[item].SetActive(!items[item].activeSelf); // toggle the selected item
    12.                 // disable all the unselected items:
    13.                 foreach (GameObject o in items)
    14.                     if (o!=items[item] && o.activeSelf)
    15.                         o.SetActive(false);
    16.             }
    17.         }
    18.     }
    19.  
    You can use the editor to place all your items in the item array and the OnGUI method will then select/toggle the item that corresponds to the pressed key.
     
  6. seejayjames

    seejayjames

    Joined:
    Jan 28, 2013
    Posts:
    692
    Bools would be good if each of the items was individual, as in having or not having one had no impact on the ability to have others. I'd use an enum in your case, and anytime the enum changes, loop through and set everything inactive except the chosen one. You can have as many other items as you want.