Delegate an event

Hi everyone, I am new at Unity and want to learn the delegate event, but I have a problem. I want when the button has been clicked, it will show some GUI button on it. I already tried the delegate, but the event is not fired (I mean the GUI button is not shown).

Here is the code that I am using:

The code below is to show the GUI button when I run the game.

public class IItemDatabase : MonoBehaviour
{
    public delegate void Action(); // Set the event for the button

    public static event Action onClicked; // The event for when the button has been clicked

    protected virtual void OnGUI()
    {
        // Call the SetStyle method
        SetStyle();

        // Set the GUIContent as the tooltip
        GUIContent buttonText = new GUIContent("Open Shop");

        // Set the GUIContent as the tooltip
        GUIContent buttonTexts = new GUIContent("Open Inventory");

        // This GUILayoutUtility is useful because it is to fit the content
        Rect buttonGUI = GUILayoutUtility.GetRect(buttonText, "Button");

        // This GUILayoutUtility is useful because it is to fit the content
        Rect buttonGUIs = GUILayoutUtility.GetRect(buttonTexts, "Button");

        // Set where have to the Rect displayed
        buttonGUI.x = 5;
        buttonGUI.y = Screen.height - 25;

        // Set where have to the Rect displayed
        buttonGUIs.x = 125;
        buttonGUIs.y = Screen.height - 25;

        // If the button has been clicked

        if (GUI.Button(buttonGUI, buttonText, style))
        {
            if (onClicked != null)
            {
                onClicked();
            }
        }

        if (GUI.Button(buttonGUIs, buttonTexts, style))
        {
            if (onClicked != null)
            {
                onClicked();
            }
        }

        // End of the clicked button event
    }
}

And here is the I want it to display when the button has been clicked:

public class IInventory : MonoBehaviour 
{

    protected virtual void OnEnable()
    {
        IItemDatabase.onClicked += DoGUI;
    }

    protected virtual void OnDisable()
    {
        IItemDatabase.onClicked -= DoGUI;
    }

    protected virtual void DoGUI()
    {
       Rect slotRect = new Rect(x * 35 + (Screen.width / 3) + 50, y * 35 + (Screen.height / 3) - 10, 30, 30);
                GUI.Box(slotRect, GUIContent.none);
    }
}

But when I clicked the button that it suppose to fired the DoGUI() in IInventory class, it does not run the function.

How do I solve this?

Thank you.

Your answer much appreciated!

I’m always happy to see questions about delegates :slight_smile:

You seem to have the idea that a delegate and event are different things. An event is a delegate - only difference event has is there is an added layer of abstraction and security that makes it impossible to set the delegate value directly, instead you’re only allowed
to add/remove methods. In other words, with delegates it is possible to do:
do myDel = value; and myDel X= value; (where X: - or +)
But with events only myEvent X= value; is allowed (where X: - or +)
A lot of times, the terms “event” and “delegate” are used interchangeably.

public delegate void Action(); // Set the event for the button

There’s already a built-in delegate called Action for you in that exact signature (in the System namespace)

I ran your scripts and they worked fine. DoGUI did get executed.

I like what you’re doing - You’re following the single responsibility principle by indirectly having your buttons reference the inventory by using delegates - because it’s not the button’s responsibility to determine what happens in an inventory +1 However; I’m not very fond of the delegate being static. I suggest the following change of design: Create a Slot class that has an Item (if you wish) - The inventory will then have an aggregate (list) of Slots - Each Slot has an onClick - When the inventory creates a slot for ex, it subscribes itself to the slot’s onClick so that when a slot/button is clicked, it indirectly notifies the inventory. No need for statics.

More delegate stuff:

  • If you want to learn everything about delegates (Actions, Funcs, Predicates, Anonymous methods, lamda expression, etc) and how they work, Jamie King is the best source.
  • See this answer here on how to
    make delegates survive an assembly
    reload.
  • For a full solution on serializable/inspectable delegate, see my
    uFAction.

I don’t do C# but don’t you need to add the brackets to call a function?

DoGUI();