- Home /
Use of Interfaces To Handle Two Object Types
I've got a UI where I want to show a text description of an object. The object will either have a Thing script or a Character script. Both of those have a GetDesc() function to return a string. In fact they inherit from a base WorldObject class. I want to say, "When the player looks at an object, get the script on that object and call its GetDesc()." Seems like a job for an interface, right? Except that I get an error if I define an interface called IDescribable and then get it like a component. ("must be convertible to a component" for me to do that", I'm told.) This doesn't work:
IDescribable temp = object_being_examined.GetComponentInChildren<IDescribable>();
The code below does work, but it's a kludge. What's the proper way to do it?
Thing temp = object_being_examined.GetComponentInChildren<Thing>();
if(temp) { examined_object_description = temp.GetDesc(); }
else
{
Character temp2 = object_being_examined.GetComponentInChildren<Character>();
examined_object_description = temp2.GetDesc();
}
Answer by _Gkxd · Apr 12, 2015 at 06:27 PM
GetComponent()
returns a Component
, so it must return a subclass of Component
. Because of this, you can't use GetComponent()
to return an arbitrary interface.
There is a workaround though, but it's a bit annoying. Instead of having an interface, you can have an abstract class, AbstractDescription
, which extends Monobehavior
. Then have an abstract method GetDesc()
in that class. By extending Monobehavior
, you can get it using GetComponent()
.
Answer by equus_ligneus · Apr 12, 2015 at 06:29 PM
GetComponent() only works on UnityEngine.Components (like MonoBehaviours). Since you have a WorldObject-class anyway, can't you either move your GetDesc() method to WorldObject or make a new, abstract class that inherits from WorldObject, move GetDesc() there and let your classes inherit from that?
GetComponent() works polymorph (if you call GetComponent() on a GameObject that has a Thing or Character, it will return that script).
In your defense: Yes, outside of Unity you would use interfaces. Inside of Unity, for the ability to use GetComponent and FindObjectOfType you'll mostly resort to (abstract) classes that inherit from MonoBehaviour.