• 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 bigpawh · Mar 24, 2022 at 06:15 PM · interfacedelegatedelegates

Can I use an interface to subscribe a script to a multicast delegate? Or, what would be a good alternative?

One of the many "golden rules" of programming is that if you're copying code, you're probably doing something wrong.

I have a singleton (gasp) that manages game ticks, and on every game tick it invokes the OnGameTick delegate.

I have many scripts that do their own things when OnGameTick is invoked, but they all do it through the DoGameTick() method. So, right now, I have all of these scripts inherit from abstract class TickUpdatingMonoBehavior, which is where the OnEnable() and OnDisable() methods subscribe and unsubscribe abstract void DoGameTick() to the OnGameTick delegate. That way, I don't need to type it out for every script, and as a bonus the compiler tells me when I haven't implemented DoGameTick().

However, this means that I cannot have these methods inherit from anything else (except other children). I want to use an interface called like IUpdateOnTick or something, but interfaces don't support default implementation and can't even call OnEnable() and OnDisable(). The interface could still define DoGameTick() but that doesn't accomplish much on its own.

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

3 Replies

· Add your reply
  • Sort: 
avatar image
Best Answer

Answer by Hellium · Mar 24, 2022 at 07:04 PM

When inheritance causes problems, composition often helps.

 public interface ITickable
 {
      void DoGameTick();
 }

 // Will automatically add TickExecutor component when this component is added
 [RequireComponent(typeof(TickExecutor))]
 public class MyMonoBehaviour : MyBaseClass, ITickable
 {
      public void DoGameTick()
      {
           Debug.Log("Tick");
      }
 }
 
 public class TickExecutor : MonoBehaviour
 {
      private ITickable tickable;
      void OnEnable()
      {
           tickable = GetComponent<ITickable>();
           if(tickable != null)
               GameManager.OnGameTick += tickable.DoGameTick;
      }
 
      void OnDisable()
      {
           if(tickable != null)
               GameManager.OnGameTick += tickable.DoGameTick;
      }
 }


Comment
bigpawh

People who like this

1 Show 3 · 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 bigpawh · Mar 26, 2022 at 04:04 PM 0
Share

Aggh but that makes DoGameTick public. Unity is really trying to force me to relax my opinions on visibility

avatar image Hellium bigpawh · Mar 26, 2022 at 04:14 PM 0
Share

It's not Unity which causes the function to be public, it's the use of the interface.

avatar image bigpawh Hellium · Mar 26, 2022 at 04:57 PM 0
Share

Right, I'm just saying in my limited time with Unity I've found that it usually requires design patters that aren't overly concerned with proper encapsulation.

For example, in one of my previous questions I was trying to add a component to an object at runtime and I wanted that component to have private fields but since you can't add components with a constructor the fields needed public setters, which otherwise wouldn't have been necessary.

In the end it doesn't really matter and I'm being obsessive.

avatar image

Answer by ArmanDoesStuff · Mar 24, 2022 at 06:49 PM

Can't you just make abstract void DoGameTick() virtual, and then override it as needed?

Comment
Hellium

People who like this

-1 Show 2 · 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 Hellium · Mar 24, 2022 at 06:53 PM 1
Share

Read the question carefully ;)

avatar image Bunny83 · Mar 24, 2022 at 09:46 PM 0
Share

An abstract method is a virtual method, just with no default implementation so a derived class is required to override the method.

avatar image

Answer by PiterQ70 · Mar 26, 2022 at 07:49 PM

IDK exactly what you want to achieve but there is couple tricks that can be useful :)

 public interface ITickable 
 { 
     protected internal void Bla() { Debug.Log(""); }
     internal void Init() { Debug.Log("Some initialization things?"); }
     
 }

 public class A : ITickable
 {
     public A()
     {
         ((ITickable)this).Init();
     }
 }

 public class B : MonoBehaviour
 {
     ITickable tickable;
     A Aclass;

     private void Awake()
     {
        
         ((ITickable)Aclass).Init();
         tickable.Init();
     }
     void Call()
     {
         ((ITickable)Aclass).Bla();
         tickable.Bla();
     }
 }

 public class C: MonoBehaviour, ITickable
 {

     private void Awake()
     {
         ((ITickable)this).Init();
         A AclassInit = new();
     }
 }

or maybe events?

 public class TickUpdater : MonoBehaviour
 {
     public static event System.Action OnTick;
     public static event System.Action<String> OnTickWithParams;

     private void Start()
     {
         OnTick();
         OnTickWithParams("some text");
     }
 }

 public interface ITickReceiver
 {
     public void RegisterEvent() { InternalRegisterEvent(); }
     private void InternalRegisterEvent() { TickUpdater.OnTick += DoTickFromInterface; }

     void DoTickFromInterface();
 }

 public class TickReceiver : MonoBehaviour, ITickReceiver
 {

     private void Awake()
     {
         TickUpdater.OnTick += DoTick;
         TickUpdater.OnTickWithParams += DoTickWithParams;
         (this as ITickReceiver).RegisterEvent();
     }

     private void DoTick() { }

     public void DoTickFromInterface() { }

     private void DoTickWithParams(string obj) { }

 }
Comment

People who like this

0 Show 5 · 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 Hellium · Mar 26, 2022 at 08:22 PM 0
Share

Unity does not support default interface members


And the current solution already uses events. The original author wants to avoid the inheritance from a class handling the subscription and unsubscription to the event.

avatar image PiterQ70 Hellium · Mar 26, 2022 at 08:34 PM 0
Share

What Unity version are you using? Unity support default interface members form 2021.2b6 Forum thread

2021.2 Docs

avatar image Hellium PiterQ70 · Mar 26, 2022 at 08:44 PM 0
Share

My bad, I got fooled by Google which got me the 2020.3 version of the documentation.

I can't blame it as it's the LTS version.

Show more comments

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

137 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 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

Using the Delegate Object design pattern in Unity 1 Answer

How to make an Input system using delegates? 0 Answers

Calling a method using delegate makes my object null 0 Answers

Need to inherit from EventArgs AND ScriptableObject 1 Answer

Is their any way to Invoke a specific delegate 1 Answer


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