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

发布时间:2021-11-15 16:20:37 作者:柒染
来源:亿速云 阅读:305

这期内容当中小编将会给大家带来有关如何用反射来实现将自定义类型显示在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上了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。

推荐阅读:
  1. 如何用Rancher在AWS上运行Kubernetes
  2. 在状态栏上显示时间

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

unity inspector

上一篇:centos7.8中firewall的操作示例

下一篇:centos下如何安装tomcat

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》