Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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
6
Question by mat · Feb 04, 2011 at 01:35 PM · inspectorinterfacefieldexpose

How to expose a field of type Interface in the inspector?

Hi,

I've found this post:

http://forum.unity3d.com/threads/49524-Exposing-fields-with-Interface-type-%28C-%29-SOLVED

but I must be missing something since I get errors!

I have an interface ISwitchableObject. Objects like lamps implement the interace. Then I have a Switch object that has a reference to an instance of an ISwitchableObject like this:

public class Switch : MonoBehaviour {

public ISwitchableObject _switchable;

}

I want to expose the _switchable field in the inspector so I can drag drop lamps and such to it. I've tried doing the below but it gives me errors (says I have invalid arguments). What am I doing wrong?

Thanks

[CustomEditor (typeof (Switch))]
public class SwitchInspector : Editor
{
   void OnInspectorGUI ()
   {
      Switch s = (Switch)target;
      s._switchable = EditorGUILayout.ObjectField ("switchable", s._switchable, typeof (ISwitchableObject));
      DrawDefaultInspector ();
   }
}

Comment
Add comment · Show 1
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 yoyo · Feb 04, 2011 at 04:47 PM 0
Share

You could make the _switchable field into an Object (or perhaps Component), then use your custom editor to make sure only Objects implementing ISwitchableObject can be assigned by the user.

10 Replies

· Add your reply
  • Sort: 
avatar image
4
Best Answer

Answer by Roland1234 · Oct 29, 2013 at 03:04 AM

Unity, by itself, does not expose fields that are of an interface type. It is possible to manually enable this functionality by implementing a custom inspector each time as Mike 3 has pointed out, but even then the reference would not be serialized ("remembered" between sessions and entering/exiting playmode).

It is possible however to create a serializable container object that wraps around a Component field (which is serialized) and casts to the desired interface type through a generic property. And with the introduction of custom property drawers into Unity, you can effectively expose a serialized interface field in your scripts without having to write a custom inspector / property drawer each time.

I've taken this approach and released an asset that does exactly that here, for anyone who's interested.

Comment
Add comment · 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
15

Answer by fresch1990 · Feb 27, 2020 at 03:04 PM

This might be irrelevant by now but jsut if someone still have the same issues:

Just add the Attributes:

 [SerializeField, SerializeReference]
 private IState currentState;  
  

That just worked for me, Cheers!
I hope this will help someone. @mat

Comment
Add comment · 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 guneyozsan · Jul 19, 2020 at 10:49 AM 1
Share

Looks like this is introduced in Unity 2019.

avatar image millerlyte87 · Aug 21, 2020 at 06:55 PM 1
Share

This was very helpful, thankyou!

avatar image alarion24 · Jan 06, 2021 at 02:54 AM 3
Share

The field is displayed after adding these attributes but is not available for drag and drop. Unable to set the reference from the inspector. Am I missing something? (tested in Unity 2020.2.0f1 and 2019.4.17f1 LTS)

avatar image rhys_vdw alarion24 · Jan 07, 2021 at 04:11 AM 1
Share

Yep, just discovered the same thing with 2019.4.14f1. Seems to not work.

avatar image N-8-D-e-v · Jan 25, 2021 at 11:50 PM 0
Share

as is the case with @alarion24 , the field is not available for drag and drop; only the name of the field in shown in the inspector (using Unity 2020.2f)

avatar image
4

Answer by Endar · Mar 01, 2018 at 03:33 PM

One way to do it is using a Component variable for what is displayed in the inspector, and a second variable of the interface that is set using the first on Start or Awake. Using the OnValidate method, you can have it check if the Component variable is of the interface, i.e. if (component is interface). If it fails that, you have it set the component to null. Example

 public Component movement;
     protected iMovement motor;
     protected void OnValidate()
     {
         if (!(movement is iMovement))
             movement = null;
     }
     protected override void Awake()
     {
         if (movement != null)
             motor = (iMovement)movement;
     }
   


This is not a perfect solution. You have to set the component to the exact component you want to use.

Comment
Add comment · 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
3

Answer by lgarczyn · Mar 08, 2017 at 01:18 AM

There's an answer that no one has suggested yet:

Instead of declaring an interface like so

 public interface IDoable {
     void DoIt();
 }
 public class Doer : MonoBehaviour, IDoable {
     public void DoIt();
 }

 public class DoableContainer : MonoBehaviour {
     public IDoable doable;
 }

just do

 public abstract class ADoable : MonoBehaviour{
     virtual void DoIt();
 }
 public class Doer : ADoable {
     public void DoIt();
 }

 public class DoableContainer : MonoBehaviour {
     public ADoable doable;
 }


Your Doer can only implement one "interface", and all your implementation of Doable have to inherit from the same class (here MonoBehaviour), but it works, is displayed, and is saved with little additional cost;

Comment
Add comment · 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 Roland1234 · Mar 08, 2017 at 02:35 AM 1
Share

Interface implementation and class inheritance may both be seen as accomplishing polymorphism, but they're really not the same things. An interface defines what an object can do, and inheritance defines what an object is.

You're right to suggest that Unity will serialize base class references, although there a few gotchas in that as well: the referenced type cannot have unresolved generic type parameters, and if you're dealing with non-Unity.Object serializable types I seem to remember Unity will forget the derived type on the next serialization cycle (in fact, I swear I saw Unity instantiate an abstract type playing around with this once, which is all sorts of messed up).

Oh, and the virtual keyword is not a class modifier and does require a method body, you were likely thinking of abstract in your example.

But cheers for the suggestion, it is an option as far as polymorphism goes.

avatar image lgarczyn Roland1234 · Mar 09, 2017 at 03:51 PM 1
Share

Changed the "virtual" ins$$anonymous$$d of "abstract", my c++ days somehow got mixed in, thanks for the correction.

Interface implementation is however not that far from inheritance. Back in c++, when you could inherit from multiple classes, interfaces where just fully abstract classes.

Changing "inherit from A implement abstract B" to "inherit from abstract B that inherits from A" is essentially the same thing (if unity does its job correctly).

avatar image xtreampb Roland1234 · Aug 24, 2021 at 11:32 PM 0
Share

I know this is a bit old but i want to make sure it is a bit clear for anyone who doesn't quite understand the differences between base classes and interfaces. A C# class can only be derived from 1 base class. Every class (unless explicitly deriving from another class) derives from the class object. To overcome this limitation, a class may implement any number of interfaces.

An interface is a contract. meaning that when you create a variable of type IMyInterface it is guaranteed to have all the members and methods of that interface. So you can safely pass it around as if it was it's own data type and what ever class actually makes up that implementation is irrelevant. Interfaces is the tooling that allows dependency injection. You can have many different implementations of the same interface, and at runtime replace them with one another. For unity, you can have one that is done in the editor, one for debugging, and yet another for your release, all without refactoring the other systems that consume the interface.

avatar image guneyozsan · Jul 19, 2020 at 10:46 AM 1
Share

If it would be limited to a single interface this would be same as class inheritance and that would be easier to maintain that way. Unfortunately this does not have much value without multiple inheritance support.

avatar image Mehrdad995 guneyozsan · Jul 30, 2021 at 11:09 AM -1
Share

I was confused by using abstracts and inheritances instead of interfaces but you can achieve the same effect with abstracts and inheritances, i.e. in the above sample you can create different Doer classes and override the ADoable as many times as you want, then reference the ADoable which is a parent class in your main class (DoableContainer), this will let you input either of your Doer overrides as you wish without the need to change anything. This absolutely works, don't worry.

avatar image
2

Answer by vexe · Sep 05, 2014 at 05:50 PM

I've answered this in-depth here: http://answers.unity3d.com/questions/783456/solution-how-to-serialize-interfaces-generics-auto.html

Checkout ShowEmAll: Serialize interfaces, generics, auto-properties, dictionaries, abstracts, etc.

Comment
Add comment · 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
  • 1
  • 2
  • ›

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

17 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

Related Questions

Loss of GO selection 2 Answers

Insert enum breaking existing inspector values 2 Answers

Exposing Variable and Enforce Component Dependencies. 1 Answer

Make a field in inspector hold inheriting classes 2 Answers

How can I get all the options this guide have in the inspector? 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