千家信息网

如何用反射来实现将自定义类型显示在Unity的Inspector上

发表于:2025-01-23 作者:千家信息网编辑
千家信息网最后更新 2025年01月23日,这期内容当中小编将会给大家带来有关如何用反射来实现将自定义类型显示在Unity的Inspector上,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。最近准备在Unit
千家信息网最后更新 2025年01月23日如何用反射来实现将自定义类型显示在Unity的Inspector上

这期内容当中小编将会给大家带来有关如何用反射来实现将自定义类型显示在Unity的Inspector上,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

最近准备在Unity调试移植的FixedB2CSharp,整个库是基于定点数的,所以首先需要将定点数序列化显示在Inspector上,没想到一脚就踩进了坑里。

一般来说,要实现我这个需求,用PropertyDrawer就好了,照着Unity的API手册改一改也就能用了。但是,我这个定点数类型还是有些不一样的,以下是关键部分代码的节选:

[Serializable]public struct Fix64{    public long RawValue { get; }    //...    public static explicit operator float(Fix64 value){        //...    }}

我可以说想尽办法也没能从SerializedProperty这个类型中直接获取到Fix64类型的目标值,所以我左思右想,既然是编辑器脚本,直接上反射试试?

说干就干,先看看API手册,怎么才能拿到目标值的引用?一般来说,这种引用都是object,所以先去看看SerializedProperty里没有object类型的成员,确认过眼神,没有。

思考一下,SerializedProperty是什么?他是想要显示在Inspector上的一个属性,和MonoBehaviourScriptableObject等类型不同,他是像Vector2一样的非UnityEngine.Object类型,所以我们拿到他所在类的实例,再通过反射去查找这个属性,不就获取到了他的值了吗?

所以我们首先通过property.serializedObject.targetObject拿到了实际上我们在Inspector上显示的UnityEngine.Object类型,然后又有了property.propertyPath提供的目录,我们很轻松的就通过反射拿到了他的父级类型的实例,为了测试,我这里写了一个MonoBehaviour脚本:

public class EditorGUITest: MonoBehaviour {   public FixedDt typeafae21;   public float xf = 1616;}[Serializable]public class FixedDt {   public Fix64 afafafafa;   public Fix64 f2wfsfaeaf;}

最终我们拿到了EditorGUITest的成员typeafae21,类型为FixedDt的实例。

最后我们通过property.name这个属性,反射获得想要的值。

思路有了代码就很简单,这里直接上完整代码:

[CustomPropertyDrawer(typeof(Fix64))]public class Fix64Drawer : PropertyDrawer {   // Draw the property inside the given rect   public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {      using (new EditorGUI.PropertyScope(position, label, property)) {         var parent = GetParentObjectOfProperty(property.propertyPath, property.serializedObject.targetObject);         var type = parent.GetType();         var pi = type.GetField(property.name);         var o = pi.GetValue(parent);         var value = (Fix64) o;         value = EditorGUI.FloatField(position, label, (float) value);         pi.SetValue(parent,value);      }   }   private object GetParentObjectOfProperty(string path, object obj) {      while (true) {         var fields = path.Split('.');         if (fields.Length == 1) {            return obj;         }         var fi = obj.GetType()                  .GetField(fields[0], BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);         obj = fi.GetValue(obj);         path = string.Join(".", fields, 1, fields.Length - 1);      }   }}

上述就是小编为大家分享的如何用反射来实现将自定义类型显示在Unity的Inspector上了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注行业资讯频道。

0