Question about events with arguments and ineritance

I’m finally getting around to using delegates and events in my code, after reading tons on the subject. But I can’t seem to accomplish what I’m going for. I have an “Entity” class which has this:

public class Entity : MonoBehaviour {

    public delegate void EntityDelegateMessage();

}

One of its child classes has this:

public class AsteroidController : Entity
{
    public static event EntityDelegateMessage EventAsteroidDestroyed;
}

I can call “EventAsteroidDestroyed” from within the AstetroidController class and my GameManager script subscribes to it like this:

        AsteroidController.EventAsteroidDestroyed += AnotherOneBitesTheDust;

This fires the proper method in GameManager and all is well. Now, I would like to send another type of message from the AsteroidController class with an accompanying integer, who’s value depends on the instance of the class sending the message (not all asteroids are worth the same number of points). So I added this in Entity:

    public delegate void EntityDelegateScore(int points);

    public static event EntityDelegateScore EventScorePoints;

Now, in the AsteroidController, if I try to send the message using:

EventScorePoints(1);

Unity (and Visual Studio) complain with the following: “The event ‘Entity.EventScorePoints’ can only appear on the left hand side of += or -= when used outside of the type `Entity’”.

What am I doing wrong? I know that if I want the instance variable I shouldn’t use a static modifier but I don’t know how this should be done.

Thanks a lot.

Look here for a MSDN article on the subject

One thing you could do is write a method like this, which you should be able to call from AsteroidController:

// defined in Entity.cs
protected static void OnEventScorePoints(int points)
{
    if(EventScorePoints != null) EventScorePoints(points);
}

Hope that helps!

I started using Action instead of delegates. It does the same thing but you don’t have to declare the delegates.

//Declaration
public static event Action NoParamsEvent;
public static event Action<int> IntEvent;
public static event Action<string> StringEvent;
public static event Action<string, int> MultipleParamsEvent;

//Extensions - you can put these methods in a static class 
 public static void Fire(this Action _action)
    {
        if(_action != null)
            _action();
    }

    public static void Fire<T>(this Action<T> _action,T _t)
    {
        if(_action != null)
            _action(_t);
    }

    public static void Fire<T, V>(this Action<T,V> _action,T _t,V _v)
    {
        if(_action != null)
            _action(_t,_v);
    }

    public static void Fire<T, V, U>(this Action<T,V,U> _action,T _t,V _v,U _u)
    {
        if(_action != null)
            _action(_t,_v,_u);
    }

    public static void Fire<T, V, U, W>(this Action<T,V,U,W> _action,T _t,V _v,U _u,W _w)
    {
        if(_action != null)
            _action(_t,_v,_u,_w);
    }

//Usability 
NoParamsEvent.Fire();
IntEvent.Fire(aInt);
StringEvent.Fire(aString);
MultipleParamsEvent.Fire(aString, aInt);

To receive the events your should register the same:

  YourClass.NoParamsEvent  += handleNoParamsEvent;
  YourClass.IntEvent += handleIntEvent;
    
    void handleNoParamsEvent()  {
    }
    
    void handleIntEvent(int _intParam) {
    }

Don’t forget to remove the listener before the gameobject is destroyed / deactivated.

YourClass.NoParamsEvent  += handleNoParamsEvent;
YourClass.IntEvent += handleIntEvent;

Usually you do += in OnEnable and -= in OnDisable.