一、Unity编辑器扩展,对自己写的组件编写编辑器样式
以下图为例,实现如图的样式。
二、创建Monobehaviour脚本
首先在非Editor文件夹中创建脚本,添加一些常见类型的字段和可序列化的类型。
public enum Course { Chinese, Mathematics, English } public class TestInspector : MonoBehaviour { public int intValue; public float floatValue; public string stringValue; public bool boolValue; public Vector3 vector3Value; public Course enumValue = Course.Chinese; public Color colorValue = Color.white; public Texture textureValue; public selfData selfData; public List<int> intList=new List<int>(); } [System.Serializable] public class selfData { public string id; public string type; public string code; public string tag; [SceneDropdown] public string scene; [SceneDropdown(new string []{"1","2","3"})] public string customScene; } public class SceneDropdownAttribute : PropertyAttribute //可以为添加该特性的字段编写特殊样式 { public string[] items; public SceneDropdownAttribute() { } public SceneDropdownAttribute(string[] items) { this.items = items; } }
三、在Editor文件夹中编写对应的Editor代码
using UnityEngine; using UnityEditor; using DataPaddyBoot.Runtime.Pool; using System.Linq; [CanEditMultipleObjects] [CustomEditor(typeof(TestInspector))] //将要重绘的target类传给Editor类 public class TestInspectorGUI : Editor { //#region 法一 ////强转为目标类 //private MyInspector _target { get { return target as MyInspector; } } ////InspectorGUI重绘 //public override void OnInspectorGUI() //{ // EditorGUILayout.BeginVertical(); // _target.intValue = EditorGUILayout.IntField("ontValue", _target.intValue); //int --> IntField // _target.floatValue = EditorGUILayout.FloatField("floatValue", _target.floatValue); //float --> FloatField // _target.stringValue = EditorGUILayout.TextField("stringValue", _target.stringValue); //string --> TextField // _target.boolValue = EditorGUILayout.Toggle("boolValue", _target.boolValue); //bool --> Toggle // _target.vector3Value = EditorGUILayout.Vector3Field("vector3Value", _target.vector3Value); //vector3 --> Vector3Field // _target.enumValue = (Course)EditorGUILayout.EnumPopup("enumValue", (Course)_target.enumValue); //enum --> EnumPopup 需要强转 // _target.colorValue = EditorGUILayout.ColorField(new GUIContent("colorValue"), _target.colorValue);//color --> ColorField // _target.textureValue = (Texture)EditorGUILayout.ObjectField("textureValue", _target.textureValue, typeof(Texture), true); //texture --> // EditorGUILayout.EndVertical(); //} //#endregion #region 法二 此脚本效果和Base.OnInspectorGUI即默认效果一样 //自定义序列化属性 private SerializedProperty intValue; private SerializedProperty floatValue; private SerializedProperty stringValue; private SerializedProperty boolValue; private SerializedProperty vector3Value; private SerializedProperty enumValue; private SerializedProperty colorValue; private SerializedProperty textureValue; private SerializedProperty selfData; private void OnEnable() { //通过名字查找序列化属性 intValue = serializedObject.FindProperty("intValue"); floatValue = serializedObject.FindProperty("floatValue"); stringValue = serializedObject.FindProperty("stringValue"); boolValue = serializedObject.FindProperty("boolValue"); vector3Value = serializedObject.FindProperty("vector3Value"); enumValue = serializedObject.FindProperty("enumValue"); colorValue = serializedObject.FindProperty("colorValue"); textureValue = serializedObject.FindProperty("textureValue"); selfData = serializedObject.FindProperty("selfData"); } public override void OnInspectorGUI() { //表示更新序列化物体 serializedObject.Update(); EditorGUILayout.PropertyField(intValue); EditorGUILayout.PropertyField(floatValue); EditorGUILayout.PropertyField(stringValue); EditorGUILayout.PropertyField(boolValue, new GUIContent("布尔"), true);//修改显示名称 if(boolValue.boolValue) { EditorGUI.indentLevel = 1;//设置缩进等级 EditorGUILayout.PropertyField(vector3Value); EditorGUI.indentLevel = 0; } EditorGUILayout.PropertyField(enumValue); EditorGUILayout.PropertyField(colorValue); EditorGUILayout.PropertyField(textureValue); EditorGUILayout.PropertyField(selfData); //应用修改的属性值,不加的话,Inspector面板修改不了 serializedObject.ApplyModifiedProperties(); } #endregion } [CustomPropertyDrawer(typeof(selfData))] public class selfDataDrawer:PropertyDrawer { bool exp = true; public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { return 0; } public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { exp = EditorGUILayout.Foldout(exp, "设置"); if(exp) { EditorGUILayout.LabelField("对象数据"); SerializedProperty idPro = property.FindPropertyRelative("id"); SerializedProperty typePro = property.FindPropertyRelative("type"); SerializedProperty codePro = property.FindPropertyRelative("code"); SerializedProperty tagPro = property.FindPropertyRelative("tag"); SerializedProperty scPro = property.FindPropertyRelative("scene"); SerializedProperty cscPro = property.FindPropertyRelative("customScene"); EditorGUILayout.BeginVertical("Box"); EditorGUILayout.PropertyField(idPro); EditorGUILayout.PropertyField(typePro); EditorGUILayout.PropertyField(codePro); EditorGUILayout.PropertyField(tagPro); EditorGUILayout.PropertyField(scPro); EditorGUILayout.PropertyField(cscPro); EditorGUILayout.EndVertical(); } } } [CustomPropertyDrawer(typeof(SceneDropdownAttribute),false)] public class SceneDropdownDrawer:PropertyDrawer { public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { return 0; } public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { SceneDropdownAttribute tar = attribute as SceneDropdownAttribute; if(tar.items==null) { //其他来源的下拉数据列表 var scenes = DataPaddyBootScenePoolManager.Instance.dataPaddySceneDataList.Select(scene => { var sceneName = scene.sceneName; return sceneName; }).ToList(); scenes.Insert(0, "无"); string curValue = property.stringValue; int curSel = scenes.FindIndex(vs => vs.Equals(curValue)); if (curSel < 0) { curSel = 0;property.stringValue = scenes[0]; } EditorGUI.BeginChangeCheck(); int newIndex = EditorGUILayout.Popup(curSel, scenes.ToArray()); if (EditorGUI.EndChangeCheck()) { property.stringValue = scenes[newIndex]; } } else { //从特性中输入下拉的数据列表 var scenes = tar.items; string curValue = property.stringValue; int curSel = ArrayUtility.IndexOf(scenes, curValue); EditorGUI.BeginChangeCheck(); int newIndex = EditorGUILayout.Popup(curSel, scenes.ToArray()); if (EditorGUI.EndChangeCheck()) { property.stringValue = scenes[newIndex]; } } } }
Unity Basic Customizations
1、unity内置的特性如 Header、Range 、Space 、Tooltip 。
2、ContextMenu Attribute,只能在方法上添加,作用是右键菜单添加一个按钮。
3、Customiz the Inspector,自定义Inspector。
4、MenuItem,增加一个菜单栏按钮。可以为这个按钮设置快捷键。
5、CustomWindow,自定义编辑器窗口。需要通过MenuItem打开窗口。
6、Gizoms 和GizmosSelected,绘制Gizoms。
7、UnityEditor.EditorUtility.SetDirty();
8、UnityEditor.PrefabUtility.InstantiatePrefab();
9、js URL.createObjectURL()
10、xNode 一个绘制流程图的框架。https://github.com/ma1238906/xNode-queueGraph