Delegates and events working?

I am trying to learn delegates and events.I want to get notified if a value changes in program so trying to write an customised event for it.I ran the below code but not working .

 public delegate  void TestDel();
    public static event TestDel testevent;

        int val = 0;
        int temp = 0;
        // Use this for initialization
        void Start ()
        {
      


        }
   
        // Update is called once per frame
        void Update ()
        {
           
        }

        public void ChangeValue()//Method for button click
        {
         temp = val;
         val = 1;
         if(temp!=val)
            {
            testevent += responsemethod;

            }
        }
        private void OnDisable()
        {
         testevent -= responsemethod;
        }



        public void responsemethod()
        {

        Debug.Log("Value Changed");
        }
testevent += responsemethod;

Here, inside your button click listener, you are just adding the event handler to the event each time the button is clicked and the values are different. Instead, you should add it earlier (and just once) and in ChangeValue method just invoke the event.

void OnEnable()
{
    testevent += responsemethod;
}

void OnDisable()
{
    testevent -= responsemethod;
}

public void ChangeValue()
{
    temp = val;
    val = 1;
    if(temp != val)
    {
        testevent.Invoke(); // or just testevent();
    }
}
2 Likes

When does the event gets enabled? Once the script is Invoked?Event is like update ?Keeps checking for whether the event is invoked?

The event is registered via the += operator. So when the script is enabled, the event is registered. You ChangeValue method will fire the event when the temp does not equal the value - via the testevent.Invoke(). It is good practice to test the event before invoking.

Something like:

if(event != null)
    event.invoke();

Or the shorthand:

event?.invoke();

Events are a way to have a pointer to a function, since gen 4 languages usually abstract out pointers.

1 Like

Looks simple but so confusing…Anyway got a better idea than before…:slight_smile:

Another way to look at is like this:

public class MyStats
    {
        public delegate void OnStatChanged();   //EVENT TYPE FOR WHEN THE STAT CHANGES
                                              
        public OnStatChanged OnValueChange;     //AN 'INSTANCE' OF THE ONSTATCHANGED TYPE
        private float _Value;                   //THE VALUE OF MYSTAT

        public float Value                      //GET - SET
        {
            get { return _Value; }              //RETURN THE VALUE OF MYSTAT
            set                                 //SET THE VALUE OF MYSTAT
            {
                _Value = value;                 //REPLACE MYSTAT VALUE WITH NEW VALUE

                OnValueChange?.Invoke();        //IF ONVALUECHANGE POINTS TO A FUNCTION, CALL IT

                //The above OnValueChanged.Invoke() in this example is akin to the following
                //LogChange();
            }
        }

        public MyStats(float value)             //ALLOCATE MEMORY FOR A STAT
        {
            Value = value;                      //REPLACE VALUE WITH PARAMETER
            OnValueChange += LogChange;         //REGISTER (POINT TO) LOG CHANGE FUNCTION
        }

        private void LogChange()
        {
            //This will display when mystat value is changed - when OnValueChanged event is called
        }
    }

This class will register the private function LogChange() to the OnValueChange event. LogChange() will be called whenever the value is changed. However, if you notice I do not register the LogChange() until after the Value is set in the constructor, which means that nothing will be logged on instantiation. Although, any changed to the value after instantiation will be logged.

In the value setter, the OnValueChange?.Invoke(), in this example, is just like calling the LogChange() function directly. But, delegates are good at maintaining encapsulation. When the value is changed, some function, or functions, will be called via the OnValueChange call. However, MyStat does not need to know about the implementaiton of the method(s) called via OnValueChange. MyStat just needs to know that something gets called when the value is changed.

Delegates and Actions are part of event driven programming. Look at any UI api, such as unity. Provided link is for a unity button’s onclick event. All unity needs to know is that when the button is clicked, we need to do something else.

https://docs.unity3d.com/ScriptReference/UI.Button-onClick.html

Unity does not expose the event. They have the AddListenerMethod. Which does something like this:

public void AddListener(Event event)
{
    buttonEvent += event;
}
1 Like

https://discussions.unity.com/t/744986 I studied delegates to solve this problem