Unity ScriptableObject自定义属性显示
1. 继承Editor,重写OnInspectorGUI方法
需求
将TestClass中intData属性和stringData按指定格式显示。
实现
定义一个测试类TestClass,一个可序列化类DataClass
[CreateAssetMenu]
public class TestClass : ScriptableObject
{
[Range(, )]
public int intData;
public string stringData;
public List<DataClass> dataList;
}
[System.Serializable]
public class DataClass
{
[Range(, )]
public int id;
public Vector3 position;
public List<int> 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, , , 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嵌套
通过Edtiro.CreateEditor可实现Editor的嵌套。
创建一个类TestClass2,它包含一个TestClass的属性。
[CreateAssetMenu]
public class TestClass2 : ScriptableObject
{
public TestClass data;
}
创建一个Test2Class的asset。它的Inspector面板的默认显示:

它并没有把TestClass的属性显示出来,如果要查看TestClass的属性,必须双击,跳到相应界面,但这样有看不到TestClass2的属性。
如果想在Test2Class的Inspector面板中直接看到并且可以修改TestClass的属性,可以重写TestClass2的Editor,并在其中嵌套TestClass的Editor。
[CustomEditor(typeof(TestClass2))]
public class TestClass2Editor : Editor
{
Editor cacheEditor;
public override void OnInspectorGUI()
{
// Update the serializedProperty - always do this in the beginning of OnInspectorGUI.
serializedObject.Update();
//显示TestClass2的默认UI
base.OnInspectorGUI();
GUILayout.Space();
var data = ( (TestClass2)target ).data;
if(data != null)
{
//创建TestClass的Editor
if (cacheEditor == null)
cacheEditor = Editor.CreateEditor(data);
GUILayout.Label("this is TestClass2");
cacheEditor.OnInspectorGUI();
}
}
}

这样就可以直接在TestClass2的面板中直接查看和编辑TestClass的属性。
2. 使用PropertyDrawer
如果想修改某种特定类型的显示,使用继承Editor的方式就会变得很麻烦,因为所有使用特定类型的asset都需要去实现一个自定义的Editor,效率非常低。这种情况就可以通过继承PropertyDrawer的方式,对指定类型的属性,进行统一显示。
需求
为Inspector面板中的所有string属性添加一个选择文件按钮,选中文件的路径直接赋值给该变量。
实现
[CustomPropertyDrawer(typeof(string))]
public class StringPropertyDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
Rect btnRect = new Rect(position);
position.width -= ;
btnRect.x += btnRect.width - ;
btnRect.width = ;
EditorGUI.BeginProperty(position, label, property);
EditorGUI.PropertyField(position, property, true);
if (GUI.Button(btnRect, "select"))
{
string path = property.stringValue;
string selectStr = EditorUtility.OpenFilePanel("选择文件", path, "");
if (!string.IsNullOrEmpty(selectStr))
{
property.stringValue = selectStr;
}
}
EditorGUI.EndProperty();
}
}

加了一个PropertyDrawer之后,Inspector面板中的所有string变量都会额外添加一个Select按钮。
注意事项
- PropertyDrawer只对可序列化的类有效,非可序列化的类没法在Inspector面板中显示。
- OnGUI方法里只能使用GUI相关方法,不能使用Layout相关方法。
- PropertyDrawer对应类型的所有属性的显示方式都会修改,例如创建一个带string属性的MonoBehaviour:

3. 使用PropertyAttribute
如果想要修改部分类的指定类型的属性的显示,直接使用PropertyDrawer就无法满足条件,这时可以结合PropertyAttribute和PropertyAttribute来实现需求。
需求
为部分指定类的int或float属性的显示添加滑动条,滑动条的上下限可根据类和属性自行设置。
实现
public class RangeAttribute : PropertyAttribute
{
public float min;
public float max;
public RangeAttribute(float min, float max)
{
this.min = min;
this.max = max;
}
}
[CustomPropertyDrawer(typeof(RangeAttribute))]
public class RangeDrawer : PropertyDrawer
{
// Draw the property inside the given rect
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
// First get the attribute since it contains the range for the slider
RangeAttribute range = attribute as RangeAttribute;
// Now draw the property as a Slider or an IntSlider based on whether it's a float or integer.
if (property.propertyType == SerializedPropertyType.Float)
EditorGUI.Slider(position, property, range.min, range.max, label);
else if (property.propertyType == SerializedPropertyType.Integer)
EditorGUI.IntSlider(position, property, (int)range.min, (int)range.max, label);
else
EditorGUI.LabelField(position, label.text, "Use Range with float or int.");
}
}
修改TestClass和DataClass
[CreateAssetMenu]
public class TestClass : ScriptableObject
{
[Range(, )]
public int intData;
public string stringData;
public List<DataClass> dataList;
}
[System.Serializable]
public class DataClass
{
[Range(, )]
public int id;
public Vector3 position;
public List<int> list;
}

其他
- 需要修改显示的类都需要满足Unity的序列化规则
- 这几种显示方式对Serializable Class都可以使用,并不需要一定是ScriptableObject。只是在编辑器下,ScriptableObject来保存临时数据比较常用,所以使用ScriptableObject来做例子。
转载请注明出处:http://www.cnblogs.com/chiguozi/p/6873050.html
Unity ScriptableObject自定义属性显示的更多相关文章
- Draw Call(Unity 5中显示为SetPass calls
Draw Call(Unity 5中显示为SetPass calls
- 自定义ScriptableObject属性显示
自定义ScriptableObject属性显示的三种方式 1. 继承Editor,重写OnInspectorGUI方法 Editor官方文档 需求 将TestClass中intData属性和strin ...
- Unity ScriptableObject的使用
ScriptableObject主要实现对象序列化的保存,因为是Unity自己的序列化,所以比xml,json序列化方便很多,但相对可控性也比较差 1.Editor下写入和读取测试: using Un ...
- Ubuntu14.04下Unity桌面托盘图标显示问题
本来想丰富一下功能,遂开始安装大开眼界:Ubuntu下10个厉害的Indicator小程序这里的Indicator小程序. 很不幸,在安装到indicator-multiload的时候,准备注销看一下 ...
- Unity 之 图片显示的真实大小
图片放入Unity中自身的属性 在做帽子游戏的时候,看到这么一段代码 //获取保龄球的自身宽度 float ballWidth=ball.GetComponent<Renderer>(). ...
- 【Unity/Kinect】显示Kinect摄像头内容,屏幕显示环境背景及人体投影
最近学习用Unity做些体感小游戏,使用Kinect的Unity插件,结合一些官方Demo学习(网上资源用Unity做的较少,蛋疼).插件及其Demo就在Unity商店里搜Kinect即可找到,其中下 ...
- Unity项目中显示项目的FPS
using UnityEngine; using System.Collections; public class ShowFpsOnGUI : MonoBehaviour { public floa ...
- Unity 3D 无法显示中文的解决方法
大家开始用unity3D时想必都会遇到一个问题,使用中文时会乱码.这是由于编码方式不同导致的,具体解决方法如下: 程序写代码什么的最好下个像Notepad++类似的工具,这里使用Notepad++修改 ...
- unity 分数的显示
通常 在完成 条件之后再增加分数 所以 一开始先增加 public int 得到分数; public Text 分数ui; 在完成条件后增加 得到分数++; 分数ui.text = 得到分数.ToSt ...
随机推荐
- PAT——1029. 旧键盘
旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现.现在给出应该输入的一段文字.以及实际被输入的文字,请你列出肯定坏掉的那些键. 输入格式: 输入在2行中分别给出应该输入的文字.以及实际 ...
- .NET Core多语言
ASP.NET Core中提供了一些本地化服务和中间件,可将网站本地化为不同的语言文化. ASP.NET Core中我们可以使用Microsoft.AspNetCore.Localization库来实 ...
- zookeeper学习记录第二篇-----安装、配置、启动
搭建zk集群,起码保证3台虚拟机的配置,本人使用的虚拟机环境为wm14+centos7+jdk1.8 下载地址 zk的tar包下载地址:http://mirror.bit.edu.cn/apache/ ...
- Java Service Wrapper 发布Java程序为Windows服务
下载Windows版本:https://www.krenger.ch/blog/java-service-wrapper-3-5-37-for-windows-x64/ 转自:F:\java\bhGe ...
- oracle数据库每天自动备份
现在介绍一下我们项目中使用exp工具每天自动对oracle进行备份. 用这个工具我们可以使用命令行的方式也可以使用pl/sql developer来进行导出. 我们要使用exp命令来导出oracle的 ...
- Instruments Time profiler 调优APP 之图片解码
以前闲时用instruments的Time profiler调试过APP,发现用tableView: cellForRowAtIndexPath: 中cell的图片设置耗时较多,之前改了一下,如下 d ...
- Objective-C 方法交换实践(三) - Aspects 源码解析
一.类与变量 AspectOptions typedef NS_OPTIONS(NSUInteger, AspectOptions) { AspectPositionAfter = 0, /// 原方 ...
- Vue聊天框默认滚动到底部
功能场景 在开发中,我们总能遇到某些场景需要运用到聊天框,比如客服对话.如果你不是一名开发人员,可能你在使用QQ或者聊天工具的时候并没有注意到,当你发出一条消息的时候,窗体会默认滚动到最底部,让用户可 ...
- swiper 仿淘宝详情页面 视频图片切换
1.好兄弟,看一下是否是你需要的 2.废话不多说 直接上代码,复制粘贴一下 自己引用一下swiper.js和css 然后就可以开始玩儿了 <!DOCTYPE html> <html& ...
- [译]C语言实现一个简易的Hash table(2)
上一章,简单介绍了Hash Table,并提出了本教程中要实现的几个Hash Table的方法,有search(a, k).insert(a, k, v)和delete(a, k),本章将介绍Hash ...
