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]