Set bool in inspector and execute Method ?

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:

        [SerializeField]
        private bool _isInteractive;

        public bool IsInteractive
        {
            get { return _isInteractive; }
            set
            {
                _isInteractive = value;
                Activate(_isInteractive);
            }
        }

        // For Testing purposes.
        // Successfully changes private field in Inspector and runs method
        protected void Update()
        {
            if (Input.GetKeyDown(KeyCode.Space))
            {
                IsInteractive = !_isInteractive;
            }
        }

    // Fancy activation code activate!
        private void Activate(bool interactable)
        {
                   Debug.Log(interactable);
        }

I can live without being able to this through the inspector, but it would make testing a mite bit easier.

Thanks!

You mean like this?

using System;
using System.Collections.Generic;
using UnityEngine;


internal class RunStuff : MonoBehaviour
{
    [SerializeField]
    protected bool RunMyStuff;

    void Update()
    {
        if (RunMyStuff)
        {
            MyStuff();
            RunMyStuff = false;
        }
    }

    protected void MyStuff()
    {
        Debug.Log("My stuff is running.");
    }

}

If you put [ExecuteInEditMode] on the class you can run it during edit time as well.

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.

1 Like

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. :slight_smile:

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.

Yes… I know I know :sweat_smile:
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 :wink:

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 … :slight_smile:

Thanks!

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.

Yes. Custom inspector is what I’m looking for.
Thanks again. :slight_smile:

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):

using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

public class ExampleScript : MonoBehaviour
{
    [SerializeField]
    private bool _isInteractive;

    public bool IsInteractive
    {
        get { return _isInteractive; }
        set
        {
            _isInteractive = value;
            Activate(_isInteractive);
        }
    }

    private void Activate(bool interactable)
    {
        Debug.Log(interactable);
    }   
}


// editor stuff


#if UNITY_EDITOR
[CustomEditor(typeof(ExampleScript))]
public class ExampleScriptEditor : Editor
{
    public ExampleScript script;
   
    public void OnEnable()
    {
        script = (ExampleScript)target;
    }

    public override void OnInspectorGUI()
    {
        bool is_interactive_target = !script.IsInteractive;
        GUI.backgroundColor = (is_interactive_target) ? Color.red : Color.green;
        if(GUILayout.Button("IsInteractive is "+script.IsInteractive+" (Click to make "+is_interactive_target+")"))
        {
            script.IsInteractive = is_interactive_target;
        }
        GUI.backgroundColor = Color.white;
        base.OnInspectorGUI();
    }
}

#endif
2 Likes

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…

2 Likes