一、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