Search code examples
c#unity-game-engine

Accessing a component's "enabled" property through an interface


I have a class / behavior MyBehavior that looks on the game object for any component that implements the interface IMyInterface using this code: myInterface = (IMyInterface)gameObject.GetComponentInParent (typeof(IMyInterface)).

IMyInterface is implemented by multiple classes / behaviors. For example:

public class MyClass1: MonoBehaviour, IMyInterface

public class MyClass2: MonoBehaviour, IMyInterface

etc etc.

I would like to be able to determine whether the MyClass1, MyClass2 etc components are enabled or disabled.

I'm not sure how to access the components however, and interfaces don't seem to have access to the enabled and disabled properties.

One solution I've thought about is to check the type explicitly e.g. myInterface is MyClass1 but this has the problem that if I ever make a new class that implements the interface I'd have to remember to come back to this MyBehavior script and update it too, which I don't like.

Are there any ways I can get the type of the class the interface is on, and access its enabled or disabled properties? Would casting it as Monobehaviour work be OK if i always expect it to be a Monobehaviour, or is that a bad idea with hidden issues?


Solution

  • If you are allowed to change IMyInterface, it is this simple:

    public interface IMyInterface {
        public bool enabled { get; set; }
    }
    

    Even if you apply an interface to a derived type in a class hierarchy, this interface can still expose any of the members that are part of that class interface, doesn't matter how far up in the inheritance chain they are.

    So this way you can ensure access to the original enabled property of MonoBehaviour (actually, its parent, Behaviour) class.


    If you aren't allowed to change IMyInterface, then yes, cast to MonoBehaviour or Behaviour instead of casting to a concrete type.

    IMyInterface myInterface = ...
    MonoBehaviour myBehaviour = (MonoBehaviour)myInterface;
    

    This is definitely not a bad practice because here you already are within MonoBehaviour paradigm by using gameObject.GetComponentInParent. This obviously won't work with C# classes, neither will this work with ScriptableObjects or other types that are not in the hierarchy of MonoBehaviour. So you are safe here.


    Comparing two approaches: as you already use interfaces, it is better to expose the property there instead of casting everything.


    Edit: basically, this is what @derhugo described in the comments. I should have probably read them all first