如何用反射来实现将自定义类型显示在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上了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注创新互联行业资讯频道。


本文名称:如何用反射来实现将自定义类型显示在Unity的Inspector上
文章链接:http://azwzsj.com/article/ihhcgg.html