Unity3D Editor 编辑器扩展3 Editor脚本
环境:Unity2017.2 语言:C#
总起:
在编辑Unity项目的时候,总不可能避免的接触到Unity自身自带的Inspector参数调整无法很好的完成某些特定功能的情况。
比方说想要一个按钮直接能跳到游戏的主界面进行调试,然而普通的情况下甚至连添加一个按钮都做不到。
这边推荐一下本人花了20几刀购买的插件——Odin Inspector & Serializer: http://sirenix.net/odininspector。该插件能够摒弃我今天要讲的Editor脚本,非常轻松的就能完成一些炫酷的EditorUI。
Odin,我其实研究的不是太深入,因为在实际的项目中并没有用到,所以该插件的介绍,我想过段时间深入研究后再说。
今天的主角是Editor脚本。
Editor脚本:
♦ 简单介绍
首先Editor脚本必须放在Editor文件夹或其子文件夹下,然后我们来看一个Edior脚本的例子:
//PlayerEditor.cs
[CustomEditor(typeof(Player))]
public class PlayerEditor : Editor
{
private SerializedProperty hpProperty;
void Awake()
{
Debug.Log("Awake");
}
void OnEnable()
{
Debug.Log("OnEnable");
hpProperty = serializedObject.FindProperty("hp");
}
public override void OnInspectorGUI()
{
// 更新serializedObject,在OnInspectorGUI一开始就要调用该函数
serializedObject.Update();
// 创建一个Int的滑动条
EditorGUILayout.IntSlider(hpProperty, 0, 100, new GUIContent("HP"));
// 使用自定义的滑动条
ProgressBar(hpProperty.intValue / 100f, "HP");
// 保存所有对脚本修改的值
serializedObject.ApplyModifiedProperties();
}
// 自定义一个滑动条
void ProgressBar(float value, string label)
{
Rect rect = GUILayoutUtility.GetRect(18, 18, "TextField");
EditorGUI.ProgressBar(rect, value, label);
EditorGUILayout.Space();
}
void OnDisable()
{
Debug.Log("OnDisable");
}
void OnDestroy()
{
Debug.Log("OnDestroy");
}
}
// Player.cs
public class Player : MonoBehaviour
{
public int hp;
}
效果如下:
可以注意到,PlayerEditor是继承于Editor的,除了Awake、OnEnable这类熟悉的生命周期方法外,脚本中很多操作使用到了UnityEditor.dll里的内容,而该dll是不会被打包的,所以非Editor文件夹底下的脚本千万不要引用到UnityEditor这个命名空间了。
Editor父类中的serializedObject代表的正是当前操作的这个脚本,使用以下操作可能更加明了:
Player player = (Player)serializedObject.targetObject;
Debug.Log(player.hp);
使用其成员变量targetObject可以直接获取到对应脚本进行操作。
具体OnInspectorGUI中的内容,我不想详细介绍了,主要是使用EditorGUILayout、GUILayout、GUILayoutUtility这三个类。
说到Editor,其实第一篇文章提到的MenuItem最好就是写在这样的脚本中。
♦ Editor脚本的结构
相比于介绍Editor的使用,我更想深入了解一下Editor这个类(使用方面,还有Odin完全可以代替Editor脚本呢)。
Editor的继承结构:Editor -> ScriptableObject -> UnityEngine.Object -> object。
Editor除了继承于ScriptableObject外,还实现了IPreviewable、IToolModeOwner接口。
我们刚刚使用的serializedObject是根据我们写的Component生成的SerializedObject(注意不是Editor的父类ScriptableObject)对象。
Editor的父类ScriptableObject可能很多人都用过,他可以很方便的保存一些配置信息,Prefab、资源引用什么的。
而SerializedObject是UnityEditor命名空间的,用于以通用的方式操作对象的属性,可以自动处理撤销操作,和产生一些预制的样式UI。
看到这里,我越来越好奇Unity的对象序列化了,但是这边反编译的C#脚本引用的都是C++内容。
感觉有些遗憾,手头也没有C++代码,如果有大神指导如何获取该源码,希望能指条明路,谢谢!
个人:
看源码的时候,多数都会追到C++的代码,看得唯一感觉比较友好的就是UGUI的,因为他基本上都是基于C#来编写的,虽然内容比较繁杂,但是总也能理清思路。
我手头上有份Unity4 C++,但感觉不是很全,Transform几个类倒是有,像SerializedObject便找不到了,可能是我姿势不对。