Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Passing a script implementing an interface through the inspector ?

Discussion in 'Scripting' started by Benji23245, Dec 1, 2023.

  1. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    208
    Hello,

    I have a Damage script which contains a DeleteObject method.

    In that method I'd like to execute a specific method from a script implementing the IDestroyEvent interface.

    That way, any object I attach the Damage script to will have the same damage behavior, but when its HP drop to zero, and thus execute DeleteObject, I can (or not) execute a "finishing method" exclusive to that object.

    But I can't pass the script through the inspector if I type it with the interface.

    So how can I do this ? I've seen some solution but they feel so hacky I'm not sure I want to use them :/

    EDIT: So I'm an idiot who completely forgot about the OnDestroy method for some reason.
    Anyway, problem solved for now !
     
    Last edited: Dec 1, 2023
    SisusCo likes this.
  2. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,266
    Just fyi, GetComponent etc. support interfaces out of the gate, without the need to do any additional work:
    Code (CSharp):
    1. public void DeleteObject()
    2. {
    3.     if(TryGetComponent(out IDestroyEvent destroyEvent))
    4.     {
    5.         destroyEvent.OnDestroying(this);
    6.     }
    7.  
    8.     Destroy(this);
    9. }
     
    Bunny83 likes this.
  3. Nad_B

    Nad_B

    Joined:
    Aug 1, 2021
    Posts:
    605
    For future reference, you can only attach to game objects scripts that inherit from
    MonoBehaviour
    . So if you want to attach a script that implements an interface, you must first make the script inherit from
    MonoBehaviour
    then add the interface(s) you want (separated with commas)


    Code (CSharp):
    1. public class MyScript : MonoBehaviour, IInterface1, IInterface2
    2. {
    3.  
    4. }
     
    Last edited: Dec 1, 2023
    Bunny83 likes this.
  4. CodeRonnie

    CodeRonnie

    Joined:
    Oct 2, 2015
    Posts:
    528
    Bunny83 likes this.
  5. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,854
    You can use my SerializableInterface. It's a simple wrapping class that actually holds a serializable UnityEngine.Object and also holds a non-serialized cached reference to the actual interface type. It comes with a propertydrawer which makes the selection / assignment really easy. When you drag a gameobject onto that field that has several components attached which all implement that interface, you will get a dropdown selection.

    With that you can simply declare a public / serialized variable like this:

    Code (CSharp):
    1. public SerializableInterface<IMyInterface> obj;
    You can actually access the serialized reference like this:

    Code (CSharp):
    1. obj.Interface.xxxx
    The whole thing is just a single script file.

    ps: you can also drag and drop ScriptableObjects onto this field as long as it implements the interface. So it works across MonoBehaviours and ScriptableObjects. Though of course you can not store a reference to a scene object in an asset. That still doesn't work. Though the other way round is no issue.
     
    CodeRonnie likes this.