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

Set bool in inspector and execute Method ?

Discussion in 'Scripting' started by FuguFirecracker, Nov 14, 2016.

  1. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    419
    Greetings,

    Is there a way that I can execute a method upon changing a boolean value in the inspector at runtime?

    I am coding up a custom UI group and am trying to propagate Interactability to the children.
    This is easy enough to do in code, but am wondering if there is some Unity Voodoo of which I am hitherto unaware.

    I thought the way forward would be with a public property with serialized private backing field, but I am unable to get the private property to propagate... Say that 3 times fast.

    Here's what I'm working with:

    Code (CSharp):
    1.  
    2.         [SerializeField]
    3.         private bool _isInteractive;
    4.  
    5.         public bool IsInteractive
    6.         {
    7.             get { return _isInteractive; }
    8.             set
    9.             {
    10.                 _isInteractive = value;
    11.                 Activate(_isInteractive);
    12.             }
    13.         }
    14.  
    15.         // For Testing purposes.
    16.         // Successfully changes private field in Inspector and runs method
    17.         protected void Update()
    18.         {
    19.             if (Input.GetKeyDown(KeyCode.Space))
    20.             {
    21.                 IsInteractive = !_isInteractive;
    22.             }
    23.         }
    24.  
    25.     // Fancy activation code activate!
    26.         private void Activate(bool interactable)
    27.         {
    28.                    Debug.Log(interactable);
    29.         }
    I can live without being able to this through the inspector, but it would make testing a mite bit easier.

    Thanks!
     
  2. Mordus

    Mordus

    Joined:
    Jun 18, 2015
    Posts:
    174
    You mean like this?
    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5.  
    6. internal class RunStuff : MonoBehaviour
    7. {
    8.     [SerializeField]
    9.     protected bool RunMyStuff;
    10.  
    11.     void Update()
    12.     {
    13.         if (RunMyStuff)
    14.         {
    15.             MyStuff();
    16.             RunMyStuff = false;
    17.         }
    18.     }
    19.  
    20.     protected void MyStuff()
    21.     {
    22.         Debug.Log("My stuff is running.");
    23.     }
    24.  
    25. }
    26.  
    27.  
    If you put [ExecuteInEditMode] on the class you can run it during edit time as well.
     
  3. Mordus

    Mordus

    Joined:
    Jun 18, 2015
    Posts:
    174
    I'll just also add a note about why your method isn't working for you

    You have a private variable that you have exposed to the editer by putting [serializefield] on it.
    You have a public property that reads/writes that variable, and you've put code in the setter to execute a function when you change it.

    What you're misunderstanding is that it's not the public property that's being exposed in the editer window when you're running the game, it's the private variable that you put [serializefield] on. A possible cause for this confusion is that the edit window formats the name of the variable and removes the _ from the start. "_isInteractive" shows as "Is Interactive".

    When you click that boolean in the edit window you're changing the private variable directly, not calling the setter on the public property. The code in the setter of your public property is simply not being executed so the function is not being called.

    Your code in the Update function works because you're setting the property. If it too set the variable directly then it too would not work.
     
    spelafort likes this.
  4. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    419
    First of all, I sincerely appreciate you taking the time to reply.
    Secondly, continuously polling for a boolean value in Update is lunacy.

    I should have been more clear.
    I know exactly what is happening in the code I wrote.
    There is no confusion.

    What I was really trying to glean was if there was possibly a processing editor directive or other Unity syntax sugar that would wire up my non-exposable public property with the exposed private backing field.

    I am utilizing the Update method in the above written code purely to inspect the one way communication from the public property to the private field. I want this communication to go both ways.

    Thanks for taking the time. :)
     
    Last edited: Nov 14, 2016
  5. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,052
    That isn't any different than than you currently have, polling for a keypress.

    You could attach a custom inspector and add a button or toggle that fires whatever code you need. The advantage there is that it won't clutter your game code with testing code, as it is ignored in builds.
     
  6. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    419
    Yes... I know I know :oops:
    I should strike that from my code example.
    That does not find its way into production code.

    It was just the quickest easiest means to access the setter.
    Seemed like overkill to set up events or break out the reactive extensions for a forum snippet ;)

    How do you feel about a quick code snippet for aforementioned custom inspector?
    Or point me towards some documents / tutorials on said subject?

    I am gonna Google... but if you got something handy ... :)

    Thanks!
     
  7. Mordus

    Mordus

    Joined:
    Jun 18, 2015
    Posts:
    174
    Nor would mine. I don't know a scenario in which a release build would have the end user opening the project in unity to click a button in the editor window to run functionality -_-. Polling a bool is the fastest and easiest way to get the functionality you're asking for, pressing a 'button' in the editor window to execute code. The performance cost of if (bool) is nothing to complain about and such tools clearly don't get put into release builds.

    The alternative is as zombiegorilla suggested, implement a custom inspector.
     
  8. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    419
    Yes. Custom inspector is what I'm looking for.
    Thanks again. :)
     
  9. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,052
    If it is some really simple/small like adding a button, I generally add it directly to the script with editor compile conditionals. So something like this would do the trick (and works in editor as well):
    Code (CSharp):
    1. using UnityEngine;
    2. #if UNITY_EDITOR
    3. using UnityEditor;
    4. #endif
    5.  
    6. public class ExampleScript : MonoBehaviour
    7. {
    8.     [SerializeField]
    9.     private bool _isInteractive;
    10.  
    11.     public bool IsInteractive
    12.     {
    13.         get { return _isInteractive; }
    14.         set
    15.         {
    16.             _isInteractive = value;
    17.             Activate(_isInteractive);
    18.         }
    19.     }
    20.  
    21.     private void Activate(bool interactable)
    22.     {
    23.         Debug.Log(interactable);
    24.     }  
    25. }
    26.  
    27.  
    28. // editor stuff
    29.  
    30.  
    31. #if UNITY_EDITOR
    32. [CustomEditor(typeof(ExampleScript))]
    33. public class ExampleScriptEditor : Editor
    34. {
    35.     public ExampleScript script;
    36.    
    37.     public void OnEnable()
    38.     {
    39.         script = (ExampleScript)target;
    40.     }
    41.  
    42.     public override void OnInspectorGUI()
    43.     {
    44.         bool is_interactive_target = !script.IsInteractive;
    45.         GUI.backgroundColor = (is_interactive_target) ? Color.red : Color.green;
    46.         if(GUILayout.Button("IsInteractive is "+script.IsInteractive+" (Click to make "+is_interactive_target+")"))
    47.         {
    48.             script.IsInteractive = is_interactive_target;
    49.         }
    50.         GUI.backgroundColor = Color.white;
    51.         base.OnInspectorGUI();
    52.     }
    53. }
    54.  
    55. #endif
    56.  
     
    manuel_garcia likes this.
  10. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    419
    Thank you so much !
    I was just in the middle of watching the tutorial: Building A Custom Inspector

    Once I learn this... I'll be unstoppable !!! Mhua-ha-ha-ha-ha-haaaaaaaaaa...
     
    Vinayak-VC and Whoaa like this.