Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • 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
0
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
Add comment
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
0

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
Add comment · 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 Event$$anonymous$$anager 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 $$anonymous$$d I've only figured out what delegates do this morning...) Thanks.

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class Event$$anonymous$$anager : $$anonymous$$onoBehaviour {
 
     public delegate void Event$$anonymous$$essage();
     public static event Event$$anonymous$$essage OnAsteroidDestroyed;
     public static event Event$$anonymous$$essage OnPlayerDestroyed;
     public static event Event$$anonymous$$essage OnLivesEqualsZero;
     public static event Event$$anonymous$$essage OnLastAsteroidDestroyed;
 
     public delegate void EventScorePoints(int points);
     public static event EventScorePoints OnScorePoints;
 
 
 
     // Events for delegate type Event$$anonymous$$essage
 
     public static void $$anonymous$$essageAsteroidDestroyed()
     {
         if (OnAsteroidDestroyed != null) OnAsteroidDestroyed();
     }
 
     public static void $$anonymous$$essageLastAsteroidDestroyed()
     {
         if (OnLastAsteroidDestroyed != null) OnLastAsteroidDestroyed();
     }
 
     public static void $$anonymous$$essagePlayerDestroyed()
     {
         if (OnPlayerDestroyed != null) OnPlayerDestroyed();
     }
 
     public static void $$anonymous$$essageLivesEqualsZero()
     {
         if (OnLivesEqualsZero != null) OnLivesEqualsZero();
     }
 
 
 
     // Events for delegate type EventScorePoints
 
     public static void $$anonymous$$essageScorePoints(int points)
     {
         if (OnScorePoints != null) OnScorePoints(points);
     }
 }
Show more comments
avatar image
0

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
Add comment · 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.

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

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

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

How to serialize fields for both base and derived classes? 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