Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Delegates/Events with Boolean parameter

Discussion in 'Scripting' started by Artpen, Jul 2, 2020.

  1. Artpen

    Artpen

    Joined:
    Jan 24, 2015
    Posts:
    291
    Hi Guys, I am trying to understand how delegates/events work. I have a simple scene with a box which green by default and should change a colour to red when I click a checkbox in Unity inspector (and then back to green if it is unchecked). Don't understand why it is not working?

    Gave Events:
    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6.  
    7. public class GameEvents : MonoBehaviour
    8. {
    9.  
    10.     public static GameEvents current;
    11.  
    12.     void Awake()
    13.     {
    14.         current = this;
    15.     }
    16.  
    17.     public event Action<bool> OnCheckboxClicked;
    18.  
    19.     public void CheckboxClicked(bool click)
    20.     {
    21.         if (OnCheckboxClicked != null)
    22.         {
    23.             OnCheckboxClicked(click);
    24.         }
    25.     }
    26.  
    27. }
    Box Controller:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5.  
    6. public class BoxController : MonoBehaviour
    7. {
    8.  
    9.     void Start()
    10.     {
    11.         GetComponent<Renderer>().material.SetColor("_Color", Color.green);
    12.         GameEvents.current.OnCheckboxClicked += ChangeColor;
    13.  
    14.     }
    15.  
    16.     private void ChangeColor(bool click)
    17.     {
    18.         if(click == true)
    19.         {
    20.             GetComponent<Renderer>().material.SetColor("_Color", Color.red);
    21.         }
    22.            
    23.     }
    24.  
    25.  
    26. }
    27.  
    Game Controller:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class GameController : MonoBehaviour
    6. {
    7.     public bool click;
    8.  
    9.   private void OnBoolenOn(bool click)
    10.     {
    11.         GameEvents.current.CheckboxClicked(click);
    12.     }
    13. }
    14.  
     
  2. Elango

    Elango

    Joined:
    Jan 27, 2016
    Posts:
    107
    Changing
    public bool click;

    from inspector will do absolutely nothing. It's not connected to OnBoolenOn in any ways.
    You need to make custom inspector or use OnValidate
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class GameController : MonoBehaviour
    6. {
    7.     public bool click;
    8.  
    9.     private void OnBoolenOn(bool click)
    10.     {
    11.         GameEvents.current.CheckboxClicked(click);
    12.     }
    13.  
    14.     private void OnValidate()
    15.     {
    16.         if(GameEvents.current != null) OnBoolenOn(click);
    17.     }
    18. }
    Altrue your code will only change color to red once and stop. It's not switching between green/red.
     
    Artpen likes this.
  3. Artpen

    Artpen

    Joined:
    Jan 24, 2015
    Posts:
    291
    Thank you @Elango. It works.I have added an IF to be able to switch between green/red.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5.  
    6. public class BoxController : MonoBehaviour
    7. {
    8.  
    9.     void Start()
    10.     {
    11.         GetComponent<Renderer>().material.SetColor("_Color", Color.green);
    12.         GameEvents.current.OnCheckboxClicked += ChangeColor;
    13.     }
    14.  
    15.     private void ChangeColor(bool click)
    16.     {
    17.  
    18.        if (click == true)
    19.         {
    20.             GetComponent<Renderer>().material.SetColor("_Color", Color.red);
    21.         } else
    22.         {
    23.             GetComponent<Renderer>().material.SetColor("_Color", Color.green);
    24.         }
    25.  
    26.     }
    27.  
    28.  
    29. }

    1.I assume same strategy will work if I will replace checkbox with UI element?

    2. May I ask you another question? This was just to test events.
    How can I use the same approach but with 3 boxes?
    I want to be able to place 3 boxes one ofter another (from left to right) and if I click OnBoolenOn for the middle box it becomes disabled (not visible) and one on the right changes its position to be right against the first one?

    Last time I tried it without events I ended up with lots of identical methods.
     
  4. Elango

    Elango

    Joined:
    Jan 27, 2016
    Posts:
    107
    1. You mean in-game UI? You won't need OnValidate for that. Just make OnBoolenOn public and assign it to Button/Toggle event.
    2. Again, if it's for inspector you'll need custom inspector.
    If it's for in-game UI you can use any Layout Group that you find suited for your needs (Horizontal for example). It will move UI elements automatically when some of them became enabled/disabled.
     
    Artpen likes this.
  5. Artpen

    Artpen

    Joined:
    Jan 24, 2015
    Posts:
    291
    1. Yes in-game UI. Ok understand. Thank you.

    2. Sorry haven't expanded it correctly. I have 3 prefabs (3 cubes) red, green and blue. Each one has BoxController attached. I have also created 3 ScriptableObjects to hold these prefabs and keep track of their location.

    I can't figure out conceptually how to keep track of every box position and be able to enable/disabled them with in-game UI. For every box in a game I need to know its position to place next one respectively.

    Start of the game - 3 boxes on the screen
    Screenshot 2020-07-02 at 14.25.14.png

    At some point user doesn't what blue box
    Screenshot 2020-07-02 at 14.25.29.png

    Or maybe two blue boxes...
    Screenshot 2020-07-02 at 14.25.54.png

    I was trying to use Unite editor check box jus for testing, so I quickly try if it works. And then develop in-game UI.

    Was thinking to use scriptable just because it is all boxes , they can just be different colour size and have different location. (Not sure I need ScriptableObjects for this)

    Thank you
     
  6. Elango

    Elango

    Joined:
    Jan 27, 2016
    Posts:
    107
    If you just need alignment, you need grid script that will move children automatically similar to UI Layout Group.
    Something like that:

    But if you want move objects with different size/location you probably will need to use physics instead.
     
  7. Artpen

    Artpen

    Joined:
    Jan 24, 2015
    Posts:
    291
    This is very interesting.
    I was hoping simply keep track of position of every gameObject so all of them know where they should appear relative to others....

    Will keep thinking