这期内容当中小编将会给大家带来有关如何用反射来实现将自定义类型显示在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
上的一个属性,和MonoBehaviour
,ScriptableObject
等类型不同,他是像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上了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/u/4589456/blog/4584877