• 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 glantucan · Sep 17, 2014 at 01:17 PM · interface

Get a component that implements a particular interface

Hi I just found this post in the forum and I'm wondering if getting an instance of Monobehaviour that implements a particular interface like this:

 IObserver observer = GetComponent(typeof(IObserver)) as IObserver;


is a bug or a feature. It works! And I find it particularly useful.

I'm using it like this for event management:

 using UnityEngine;
 using System.Collections;
 
 public class GameManager : MonoBehaviour 
 {
 
     public EventDispatcher EventManager =  new EventDispatcher();
 
 
     // Use this to find IObservers already on the scene
     void Awake () 
     {
         GameObject[] observers = GameObject.FindGameObjectsWithTag ("ListenerObject");
 
         foreach(GameObject observer in observers)
         {
             IObserver observerBe = observer.GetComponent(typeof(IObserver)) as IObserver;
             if (observerBe != null)
             {
                 observerBe.EventManager = EventManager;
             }
         }
 
     }

     void Update () 
     {
         if(Time.time > 5)
         {
             EventManager.Dispatch<MoveEvent>();
         }
     }
 }

Where the EventDispatcher class is very similar to this one, but without the singleton part, which I personally don't like. I can post my code if anyone is interested.

The point is that this approach doesn't work with the generic version of GetComponent,

``` IObserver observer = GetComponent(); ```

produces an error:

 The type `IObserver' must be convertible to `UnityEngine.Component' in order to use it as parameter `T' in the generic type or method `UnityEngine.Component.GetComponent<T>()'

Which sounds logical, and makes the working version feel like a hack.

Comment
Add comment · Show 4
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 Baste · Sep 17, 2014 at 03:59 PM 0
Share

I've seen this particularity of the generic vs. non-generic GetComponent before, and it's pretty weird.

Note that the documentation for GetComponent specifies that it "Returns the component of Type type if the game object has one attached, null if it doesn't". Which doesn't say anything about what should happen if we ask for a Component through a Type that doesn't inherit from Component.

So the docs doesn't say which of the behaviours you are seeing is the correct one. Which means that you shouldn't count on the behaviour you're seeing in the non-generic version staying around in future updates.

avatar image glantucan · Sep 17, 2014 at 05:11 PM 0
Share

It's a shame things are so unclear about this, specially when Unity's site has a tutorial about using interfaces. What's the use of them if you can't use them with your $$anonymous$$onoBehaviours? I mean if future releases might make them useless. :(

avatar image glantucan · Sep 17, 2014 at 05:25 PM 0
Share

Well, I found this which might be more verbose, but it's safe in terms of future API?? changes.

Applied to the case above:

 //...
 void Awake ()
 {
     GameObject[] observers = GameObject.FindGameObjectsWithTag ("ListenerObject");
  
     foreach(GameObject observer in observers)
     {
         $$anonymous$$onoBehaviour[] list = observer.GameComponents<$$anonymous$$onoBehaviour>();
         foreach($$anonymous$$onoBehaviour mb in list)
         {
             if (mb is IObservable)
             {
                 observerBe.Event$$anonymous$$anager = Event$$anonymous$$anager;
             }
         }
     }
 }

avatar image glantucan · Sep 19, 2014 at 11:01 AM 0
Share

I found another approach using linq here,

 IObserver observerBe = observer.GetComponents<$$anonymous$$onoBehaviour>.Where(c=>c is IObserver).Cast(IObserver);

I don't know whether linq behaves well with the mono libraries version Unity uses. I remember reading something about it (clai$$anonymous$$g that it doesn't and can be cause of memory leaks) but don't ask me where.

0 Replies

· Add your reply
  • Sort: 

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

OnPointerEnter and OnPointerExit not being triggered 0 Answers

Starting with UNITY. what first? 1 Answer

Interface 3D 1 Answer

Problems with GUI 0 Answers

Exposing interface implementation 3 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