• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
Question by Cirrocumulus · Jan 24, 2018 at 06:44 PM · inheritanceevents

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.

Comment

People who like this

0 Show 0
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image

Answer by callen · Jan 24, 2018 at 07:02 PM

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!

Comment

People who like this

0 Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Cirrocumulus · Jan 24, 2018 at 07:21 PM 0
Share

Thank you. I've read the article (which is in line with your suggestion). This solution works, but there are two things I don't understand (the second one is more mysterious to me) : (1) Isn't there a more elegant solution than the wrapping of the event in a method? (2) How on Earth does this work correctly with instanced members of a class (I've tried, there's no problem with that, each instance can send its own message), when the event is defined as static. Doesn't the event belong to the class rather than to the instances when marked as static?

avatar image Bunny83 Cirrocumulus · Jan 24, 2018 at 07:43 PM 0
Share

No, the point is an event (so a delegate variabe with the event keyword) can only be invoked inside the class it is defined. Since the base class provides the event it's responsible for calling it.


Another solution is to not use an event but simply a delegate. If you declare it like this:

 public static EntityDelegateScore EventScorePoints;

It should do what you want. However you loose encapsulation. So everybody can invoke that delegate. Subscribing and unsubscribing works the same way.

avatar image Cirrocumulus Bunny83 · Jan 24, 2018 at 10:05 PM 0
Share

After much digging I've abandoned the idea of delegates inside the base Entity class and child classes, because it seemed too fragmented. I've come up with an EventManager class on which I can call methods from anywhere and it then handles the messaging globally. Does it seem logical (or conversely, very silly) to do things that way? It works as expected on my end, but I don't know if it's considered good practice (please bear in mind I've only figured out what delegates do this morning...) Thanks.

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class EventManager : MonoBehaviour {
 
     public delegate void EventMessage();
     public static event EventMessage OnAsteroidDestroyed;
     public static event EventMessage OnPlayerDestroyed;
     public static event EventMessage OnLivesEqualsZero;
     public static event EventMessage OnLastAsteroidDestroyed;
 
     public delegate void EventScorePoints(int points);
     public static event EventScorePoints OnScorePoints;
 
 
 
     // Events for delegate type EventMessage
 
     public static void MessageAsteroidDestroyed()
     {
         if (OnAsteroidDestroyed != null) OnAsteroidDestroyed();
     }
 
     public static void MessageLastAsteroidDestroyed()
     {
         if (OnLastAsteroidDestroyed != null) OnLastAsteroidDestroyed();
     }
 
     public static void MessagePlayerDestroyed()
     {
         if (OnPlayerDestroyed != null) OnPlayerDestroyed();
     }
 
     public static void MessageLivesEqualsZero()
     {
         if (OnLivesEqualsZero != null) OnLivesEqualsZero();
     }
 
 
 
     // Events for delegate type EventScorePoints
 
     public static void MessageScorePoints(int points)
     {
         if (OnScorePoints != null) OnScorePoints(points);
     }
 }
Show more comments
avatar image

Answer by Neamtzu · Feb 05, 2018 at 01:21 PM

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.

Comment

People who like this

0 Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Cirrocumulus · Feb 05, 2018 at 01:32 PM 0
Share

I agree, since I discovered it I find it much more concise. Just commented about that yesterday :) https://answers.unity.com/comments/1464175/view.html

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Update about the future of Unity Answers

Unity Answers content will be migrated to a new Community platform and we are aiming to launch a public beta later in June. Please note, we are aiming to set Unity Answers to read-only mode on the 31st of May in order to prepare for the final data migration.

For more information, please read our full announcement.

Follow this Question

Answers Answers and Comments

79 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Interaction script 2 Answers

Inheritance that changes how events are handled. (C#) 1 Answer

How do I show UnityEvent in inspector on Inheritance class of ScrollRect ? 2 Answers

An OS design issue: File types associated with their appropriate programs 1 Answer

Inheriting from a class that inherits from NetworkBehaviour 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges