博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Unity ScriptableObject自定义属性显示
阅读量:6083 次
发布时间:2019-06-20

本文共 5822 字,大约阅读时间需要 19 分钟。

1. 继承Editor,重写OnInspectorGUI方法

需求

将TestClass中intData属性和stringData按指定格式显示。

实现

定义一个测试类TestClass,一个可序列化类DataClass

[CreateAssetMenu]public class TestClass : ScriptableObject{    [Range(0, 10)]    public int intData;    public string stringData;    public List
dataList;}[System.Serializable]public class DataClass{ [Range(0, 100)] public int id; public Vector3 position; public List
list;}

 

//指定类型[CustomEditor(typeof(TestClass))]public class TestClassEditor  : Editor{    SerializedProperty intField;    SerializedProperty stringField;    void OnEnable()    {        intField = serializedObject.FindProperty("intData");        stringField = serializedObject.FindProperty("stringData");    }    public override void OnInspectorGUI()    {        // Update the serializedProperty - always do this in the beginning of OnInspectorGUI.        serializedObject.Update();        EditorGUILayout.IntSlider(intField, 0, 100, new GUIContent("initData"));        EditorGUILayout.BeginHorizontal();        EditorGUILayout.PropertyField(stringField);        if(GUILayout.Button("Select"))        {            stringField.stringValue = EditorUtility.OpenFilePanel("", Application.dataPath, "");        }        EditorGUILayout.EndHorizontal();        // Apply changes to the serializedProperty - always do this in the end of OnInspectorGUI.        //需要在OnInspectorGUI之前修改属性,否则无法修改值        serializedObject.ApplyModifiedProperties();        base.OnInspectorGUI();    }}

Editor嵌套

通过可实现Editor的嵌套。

创建一个类TestClass2,它包含一个TestClass的属性。

[CreateAssetMenu]public class TestClass2 : ScriptableObject{    public TestClass data;}

创建一个Test2Class的asset。它的Inspector面板的默认显示:

它并没有把TestClass的属性显示出来,如果要查看TestClass的属性,必须双击,跳到相应界面,但这样有看不到TestClass2的属性。

如果想在Test2Class的Inspector面板中直接看到并且可以修改TestClass的属性,可以重写TestClass2的Editor,并在其中嵌套TestClass的Editor。

1 [CustomEditor(typeof(TestClass2))] 2 public class TestClass2Editor : Editor 3 { 4     Editor cacheEditor; 5     public override void OnInspectorGUI() 6     { 7         // Update the serializedProperty - always do this in the beginning of OnInspectorGUI. 8         serializedObject.Update(); 9         //显示TestClass2的默认UI10         base.OnInspectorGUI();11         GUILayout.Space(20);12         var data = ( (TestClass2)target ).data;13         if(data != null)14         {15             //创建TestClass的Editor16             if (cacheEditor == null)17                 cacheEditor = Editor.CreateEditor(data);18             GUILayout.Label("this is TestClass2");19             cacheEditor.OnInspectorGUI();20         }21     }22 }

这样就可以直接在TestClass2的面板中直接查看和编辑TestClass的属性。

2. 使用PropertyDrawer

如果想修改某种特定类型的显示,使用继承Editor的方式就会变得很麻烦,因为所有使用特定类型的asset都需要去实现一个自定义的Editor,效率非常低。这种情况就可以通过继承PropertyDrawer的方式,对指定类型的属性,进行统一显示。

需求

为Inspector面板中的所有string属性添加一个选择文件按钮,选中文件的路径直接赋值给该变量。

实现

1 [CustomPropertyDrawer(typeof(string))] 2 public class StringPropertyDrawer : PropertyDrawer 3 { 4     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 5     { 6         Rect btnRect = new Rect(position); 7         position.width -= 60; 8         btnRect.x += btnRect.width - 60; 9         btnRect.width = 60;10         EditorGUI.BeginProperty(position, label, property);11         EditorGUI.PropertyField(position, property, true);12         if (GUI.Button(btnRect, "select"))13         {14             string path = property.stringValue;15             string selectStr = EditorUtility.OpenFilePanel("选择文件", path, "");16             if (!string.IsNullOrEmpty(selectStr))17             {18                 property.stringValue = selectStr;19             }20         }21         EditorGUI.EndProperty();22     }23 }

加了一个PropertyDrawer之后,Inspector面板中的所有string变量都会额外添加一个Select按钮。

注意事项

  1. PropertyDrawer只对可序列化的类有效,非可序列化的类没法在Inspector面板中显示。
  2. OnGUI方法里只能使用GUI相关方法,不能使用Layout相关方法。
  3. PropertyDrawer对应类型的所有属性的显示方式都会修改,例如创建一个带string属性的MonoBehaviour:

3. 使用PropertyAttribute

如果想要修改部分类的指定类型的属性的显示,直接使用PropertyDrawer就无法满足条件,这时可以结合PropertyAttribute和PropertyAttribute来实现需求。

需求

为部分指定类的int或float属性的显示添加滑动条,滑动条的上下限可根据类和属性自行设置。

实现

 

1 public class RangeAttribute : PropertyAttribute 2 { 3     public float min; 4     public float max; 5     public RangeAttribute(float min, float max) 6     { 7         this.min = min; 8         this.max = max; 9     }10 }11 [CustomPropertyDrawer(typeof(RangeAttribute))]12 public class RangeDrawer : PropertyDrawer13 {14     // Draw the property inside the given rect15     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)16     {17         // First get the attribute since it contains the range for the slider18         RangeAttribute range = attribute as RangeAttribute;19         // Now draw the property as a Slider or an IntSlider based on whether it's a float or integer.20         if (property.propertyType == SerializedPropertyType.Float)21             EditorGUI.Slider(position, property, range.min, range.max, label);22         else if (property.propertyType == SerializedPropertyType.Integer)23             EditorGUI.IntSlider(position, property, (int)range.min, (int)range.max, label);24         else25             EditorGUI.LabelField(position, label.text, "Use Range with float or int.");26     }27 }

修改TestClass和DataClass

1 [CreateAssetMenu] 2 public class TestClass : ScriptableObject 3 { 4     [Range(0, 10)] 5     public int intData; 6     public string stringData; 7     public List
dataList; 8 } 9 [System.Serializable]10 public class DataClass11 {12 [Range(0, 100)]13 public int id;14 public Vector3 position;15 public List
list;16 }

其他

  • 需要修改显示的类都需要满足
  • 这几种显示方式对Serializable Class都可以使用,并不需要一定是ScriptableObject。只是在编辑器下,ScriptableObject来保存临时数据比较常用,所以使用ScriptableObject来做例子。

转载请注明出处: 

转载于:https://www.cnblogs.com/chiguozi/p/6873050.html

你可能感兴趣的文章
java基础讲解06-----字符串
查看>>
会计的思考(44):史上最富有的会计--洛克菲勒的会计视角
查看>>
宏的写法和特点
查看>>
OC门的工作原理
查看>>
《Spring1之第八次站立会议》
查看>>
关于mysql的初步学习 (一)
查看>>
VB6在win10下的使用经验
查看>>
DB2数据库中得到当前年月日,时分秒的语句
查看>>
IOS第三方地图-百度地图集成
查看>>
swift学习网站
查看>>
DocumentFragments
查看>>
HTTP-web-Internet
查看>>
【 D3.js 入门系列 — 4 】 如何使用比例尺( scale )
查看>>
Android优化后的定时器代码
查看>>
Html.RenderPartial("")与Html.Partial("")区别
查看>>
poj2524 Ubiquitous Religions(并查集)
查看>>
POJ 1905, Expanding Rods
查看>>
微信内移动前端开发抓包调试工具fiddler使用教程
查看>>
在Windows及Linux下获取毫秒级运行时间的方法
查看>>
【原创】Ubuntu以root用户自动登录
查看>>