acecase 发表于 2022-5-26 18:58

Unity中,在Inspector窗口显示接口类型的字段

需求

原始需求


Enemy实际根据其Atk进行区分,即允许为不同的Enemy配置相应的Atk(如MeleeAtk,RangeAtk……),希望能在Inspector面板上配置。
需求提取


提供一个接口IEnemyAtk,其包含了一个方法Attack(),各EnemyAtk类(如MeleeAtk,RangeAtk……)需实现该接口。
实际效果

Enemy的字段InterfaceHelper在Inspector中的显示效果


image.png

如何把IEnemyAtk显示在Inspector窗口中?

思路

提供一个类:InterfaceHelper,其有一个Component字段_target(将实际实现接口的类实例存放在此处),外部可通过InterfaceHelper提供的GetInterface方法获得前述“接口”。自定义InterfaceHelper作为某个MonoBehavior的一个字段时的显示形式:将其_target字段显示出来。
相关代码

Enemy中的字段
        private InterfaceHelper EnemyAtkPack;    private IEnemyAtk EnemyAtk{ get { return EnemyAtkPack.GetInterface<IEnemyAtk>(); } }
IEnemyAtk接口
interface IEnemyAtk{    void Attack();}
实现了IEnemyAtk接口的EnemyRangeAtk
public class EnemyRangeAtk : MonoBehaviour, IEnemyAtk{}
InterfaceHelper及其作为属性时的自定义绘制
using UnityEngine;#if UNITY_EDITORusing UnityEditor;#endifpublic class InterfaceHelper{        private Component _target;    public T GetInterface<T>() where T : class    {      return _target as T;    }}#if UNITY_EDITOR// 如何绘制指定类型(InterfaceHelper)的属性public class EditorInterfaceHelper : PropertyDrawer{    public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)    {      EditorGUI.BeginProperty(pos, label, prop);      pos = EditorGUI.PrefixLabel(pos, GUIUtility.GetControlID(FocusType.Passive), label);      EditorGUI.PropertyField(pos, prop.FindPropertyRelative("_target"), GUIContent.none);      EditorGUI.EndProperty();    }}#endif
页: [1]
查看完整版本: Unity中,在Inspector窗口显示接口类型的字段