1. 基本介绍
1. MenuItem
- 使用 MenuItem 特性,让静态函数作为一个菜单栏功能
[MenuItem(“Tools/mytest”)]
- 第三个参数层级,可控制显示的顺序。不同级别的参数最小值和最大值之间最小为11
- 添加快捷键
- %-CTRL
- # -Shift
- & -Alt
[MenuItem( “Tools/New Option %#a” )] 即Alt+Shift+A [MenuItem( “Tools/Item2 _g” )] 即G
- 特殊路径
- Assets/[] -添加到“Assets”菜单下,同时也显示在右键单击项目视图时弹出的菜单中。
- Asset/Create/[] - 添加在“Assets ->Create”子菜单中。
- CONTEXT/[任意组件名]/[] - 菜单项将出现在给定组件的右键单击菜单中。
[MenuItem("CONTEXT/Rigidbody/Do Something")]
public static void DoSomething (MenuCommand command) {
Rigidbody body= command.context as Rigidbody ;
body.mass = 5 ;
}
- GameObject/[] 菜单项会出现在层级的右键菜单中。但你需要给定一个层级 < 50
[MenuItem(“GameObject/mytest2”, false, 12)]
- 限定 通过第二个参数来限定该按钮是否启用
// 效果
[MenuItem("Assets/SetMass", false, 12)]
static void SetMass()
{
Rigidbody rigidbody = Selection.gameObjects[0].GetComponent();
rigidbody.mass = 5;
}
// 约束
[MenuItem("Assets/SetMass", true)]
static bool SetMassOption()
{
return Selection.gameObjects[0].GetComponent() != null;
}
2. AddComponentMenu
添加组件到“添加组件”菜单下。
3. ContextMenu、ContextMenuItem在继承MonoBehaviour时:
特性描述ContextMenu添加到自身的右键菜单中ContextMenuItem添加到菜单列表public class MyObject : MonoBehaviour
{
[ContextMenuItem("+1", "AddValue")]
public int value;
public string data;
[ContextMenu("重置")]
void ResetData()
{
value = 0;
data = "";
}
void AddValue()
{
value++;
}
}
4. ScriptableWizard
继承该类可生成一个点击后关闭并重置的面板,可进行方便的对象创建修改操作
using UnityEngine;
using UnityEditor;
public class MyObjectEditor : ScriptableWizard
{
// 参数
public string changeName = "未命名";
// 创建按钮到编辑器,并设置按钮名称以及标题
[MenuItem("Tools/CreateWizard")]
public static void CreateWizard()
{
// 一个点击后关闭并重置的面板
DisplayWizard("统一修改", "修改", "第二个按钮");
}
// 点击后关闭界面并执行
private void OnWizardCreate()
{
// 修改选取对象的名字
foreach (var obj in Selection.gameObjects)
{
// 操作记录到unity记录中,以便ctrl+z撤回
Undo.RecordObject(obj, "修改名字");
obj.name = changeName;
}
// 在界面显示提示信息,仅在未关闭时显示
ShowNotification(new GUIContent(Selection.gameObjects.Length + "个对象被修改了"));
}
// 点击另一个按钮,这不会关闭界面
private void OnWizardOtherButton() => OnWizardCreate();
// 仅在初始化和值改变时变化
private void OnWizardUpdate() => HelpInfor();
// 选中物体时调用
private void OnSelectionChange() => HelpInfor();
// 用于提示信息
void HelpInfor()
{
if (Selection.gameObjects.Length == 0)
{
// 错误信息
errorString = "请选择一个对象!";
helpString = "";
}
else
{
// 帮助信息
errorString = "";
helpString = "您选择了" + Selection.gameObjects.Length + "个对象";
}
}
}
5. [UnityEditor.InitializeOnLoadMethod]
每次Unity编译都会运行一次
2. 编译器绘图 1. 绘图方法- GUILayout
- EditorGUILayout
主面板
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class AudioWindowEditor : EditorWindow
{
static SaveData data;
string path = "Assets/Resources/MainData.asset";
string text;
string search = "";
static GUIStyle textStyle;
static AudioWindowEditor window;
[MenuItem("Tools/test")]
public static void CreateWindow()
{
// 固定大小窗口
// Rect rect = new Rect(0, 0, 800, 600);
// AudioWindowEditor window = GetWindowWithRect(typeof(AudioWindowEditor), rect) as AudioWindowEditor;
if (window == null)
{
window = GetWindow("数据管理");
textStyle = new GUIStyle("HeaderLabel");
textStyle.fontSize = 24;
}
window.Show();
}
///
/// 每秒调用十次
///
private void OnInspectorUpdate()
{
}
private void OnGUI()
{
// 设置标题和其显示的值,将其值返回
// text = EditorGUILayout.TextField("输入文字", text);
if (data == null) data = AssetDatabase.LoadAssetAtPath(path);
if (data == null)
{
// new SaveData()可替换为 CreateInstance()
AssetDatabase.CreateAsset(new SaveData(), path);
AssetDatabase.SaveAssets();
data = AssetDatabase.LoadAssetAtPath(path);
}
var settings = new SerializedObject(data);
GUI.skin.label.fontSize = 16;
GUILayout.Label("基本内容");
EditorGUILayout.PropertyField(settings.FindProperty("key"), new GUIContent("名称"));
// 第一栏
// GUILayout.BeginHorizontal("Wizard Box");
search = EditorGUILayout.TextField("", search, "SearchTextField");
// GUILayout.EndHorizontal();
// 第二栏
GUILayout.BeginVertical("Wizard Box", GUILayout.MaxHeight(1));
GUILayout.BeginHorizontal(new GUIStyle("HelpBox")
{
padding = new RectOffset(10, 0, 4, 4)
});
GUILayout.Label("名称", new GUIStyle("SettingsHeader")
{
fontSize = 16,
alignment = TextAnchor.MiddleLeft,
});
GUILayout.Label("值", new GUIStyle("SettingsHeader")
{
fontSize = 16,
alignment = TextAnchor.MiddleLeft,
});
GUILayout.EndHorizontal();
KeyValue removeOne = null;
KeyValue moveUp = null;
KeyValue moveDown = null;
// 这其实是错误的写法,不应该直接操纵数据源,而是通过settings.FindProperty("datas")arraySize和settings.FindProperty("datas").GetArrayElementAtIndex(i)
for (int i = 0; i = 0; i--)
{
var index = selectedIndices[i];
list.Deselect(index);
AskRemoveVariable(variables, index);
}
}
protected virtual void AskRemoveVariable(SerializedProperty variables, int index)
{
if (variables == null || index = variables.arraySize)
return;
var variable = variables.GetArrayElementAtIndex(index);
var name = variable.FindPropertyRelative("name").stringValue;
// 某项被填入值时,弹出提示避免直接清除
if (string.IsNullOrEmpty(name))
{
RemoveVariable(variables, index);
return;
}
if (EditorUtility.DisplayDialog("Confirm delete",
string.Format("Are you sure you want to delete the item named \"{0}\"?", name), "Yes", "Cancel"))
RemoveVariable(variables, index);
}
protected virtual void RemoveVariable(SerializedProperty variables, int index)
{
if (index = variables.arraySize)
return;
variables.serializedObject.Update();
//清除表单元素
variables.DeleteArrayElementAtIndex(index);
//写入数据到实例化对象
variables.serializedObject.ApplyModifiedProperties();
GUI.FocusControl(null);
}
private void DrawElementBackground(Rect rect, int index, bool isActive, bool isFocused)
{
ReorderableList.defaultBehaviours.DrawElementBackground(rect, index, isActive, false, true);
}
}