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:
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().
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.