1. 继承Editor,重写OnInspectorGUI方法

Editor官方文档

需求

将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

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按钮。

注意事项

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

3. 使用PropertyAttribute

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

自定义ScriptableObject属性显示的更多相关文章

  1. html5的自定义data-*属性和jquery的data()方法的使用示例

    人们总喜欢往HTML标签上添加自定义属性来存储和操作数据. 但这样做的问题是,你不知道将来会不会有其它脚本把你的自定义属性给重置掉,此外,你这样做也会导致html语法上不符合Html规范,以及一些其它 ...

  2. iOS8自定义推送显示按钮及推送优化

    http://www.jianshu.com/p/803bfaae989e iOS8自定义推送显示按钮及推送优化 字数1435 阅读473 评论0 喜欢2 导语 在iOS8中,推送消息不再只是简单地点 ...

  3. WPF自定义窗口最大化显示任务栏

    原文:WPF自定义窗口最大化显示任务栏 当我们要自定义WPF窗口样式时,通常是采用设计窗口的属性 WindowStyle="None" ,然后为窗口自定义放大,缩小,关闭按钮的样式 ...

  4. Django(四) 后台管理:创建管理员、注册模型类、自定义管理页面显示内容

    后台管理 第1步.本地化:设置语言.时区 修改project1/settings.py #LANGUAGE_CODE = 'en-us' LANGUAGE_CODE = 'zh-hans' #设置语言 ...

  5. Android之探究viewGroup自定义子属性参数的获取流程

    通常会疑惑,当使用不同的布局方式时,子view得布局属性就不太一样,比如当父布局是LinearLayout时,子view就能有效的使用它的一些布局属性如layout_weight.weightSum. ...

  6. 直接用<img> 的src属性显示base64转码后的字符串成图片

    直接用<img> 的src属性显示base64转码后的字符串成图片 <img src="base64转码后的字符串" ></img> 下面的图片 ...

  7. Android读取自定义View属性

    Android读取自定义View属性 attrs.xml : <?xml version="1.0" encoding="utf-8"?> < ...

  8. 自定义Property属性动画

    同步发表于 http://avenwu.net/customlayout/2015/04/06/custom_property_animation/ 代码获取 git clone https://gi ...

  9. android自定义view属性

    第一种 /MainActivity/res/values/attrs.xml <?xml version="1.0" encoding="utf-8"?& ...

随机推荐

  1. cephfs创建及挂载

    Ceph 文件系统( Ceph FS )是个 POSIX 兼容的文件系统,它使用 Ceph 存储集群来存储数据.Ceph 文件系统要求 Ceph 存储集群内至少有一个 Ceph 元数据服务器. 1.添 ...

  2. *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ViewController > setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key

    *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ViewController > ...

  3. Cobbler自动化部署最佳实践

    第1章 Cobbler自动化部署最佳实践 运维自动化在生产环境中占据着举足轻重的地位,尤其是面对几百台,几千台甚至几万台的服务器时,仅仅是安装操作系统,如果不通过自动化来完成,根本是不可想象的. 面对 ...

  4. 【CreateJS】WebStorm+Adobe Animate CC 搭配开发HTML5,入门教程

    目的:动画设计师用Adobe Animate CC做好动画素材,发布好之后,交给程序员写交互代码:在WebStorm之类的ide里操纵 Animate 里面的变量,class等. 前提环境: ①安装好 ...

  5. 老李推荐: 第3章1节《MonkeyRunner源码剖析》脚本编写示例: MonkeyRunner API使用示例

    老李推荐: 第3章1节<MonkeyRunner源码剖析>脚本编写示例: MonkeyRunner API使用示例   MonkeyRunner这个类可以说是编写monkeyrunner脚 ...

  6. number问题

    Missing Number Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one ...

  7. c#控制台实现post网站登录

    如题,首先我写了一个web页面来实现post登陆,只做演示,代码如下 public void ProcessRequest(HttpContext context) { context.Respons ...

  8. Linux-进程描述(2)之进程标识符与进程位置

    在上一篇文章中详细介绍了task_struct结构体内的常见成员,然后我们就来看一下具体内容.每个进程都把它的信息放在 task_struct 这个数据结构中,task_struct 包含了这些内容: ...

  9. 利用 force recovery 解决服务器 crash 导致 MySQL 重启失败的问题

    小明同学在本机上安装了 MySQL 5.7.17 配合项目进行开发,并且已经有了一部分重要数据.某天小明在开发的时候,需要出去一趟就直接把电脑关掉了,没有让 MySQL 正常关闭,重启 MySQL 的 ...

  10. QT5 && VS2013配置

    1.下载安装包 qt-opensource-windows-x86-msvc2013_64-5.7.0.exe VS2013_RTM_ULT_ENU.iso 插件:qt-vs-addin-msvc20 ...