赞
踩
MemuItem
MenuItem 属性用于向主菜单和检视面板上下文菜单添加菜单项。
该 MenuItem 属性能够将任何静态函数转变为菜单命令。仅静态函数可使用 MenuItem 属性。
热键 | 内容 |
---|---|
% | 在Windows和Linux上为ctrl,在macOS上为cmd |
^ | 在Windows、Linux和macOS上的ctrl |
# | shift |
& | alt |
_X | 字母热键 _g _x _a 等等 |
支持一些特殊的键盘键作为热键,例如“#LEFT”将映射为向左移动。像这样支持的键有:LEFT、RIGHT、UP、DOWN、F1···F12,HOME,END,PGUP,PGDN,INS,DEL,TAB,SPACE。
[MenuItem (string itemName, bool isValidateFunction, int priority)]
[MenuItem("MyMenu/1",false,1)]
static void Test1() {
Debug.Log("1111");
}
[MenuItem("MyMenu/1", true, 3)]
static bool Test2() {
Debug.Log("Test");
return false;
}
有效验证:相同的
itemName,当验证函数返回false时,那么Test1则不会调用(无法调用)
判断的是3和14
// 单一个字母
[MenuItem("MyMenu/Test _g")]
static void Test() {
Debug.Log("Test");
}
// 热键+字母
[MenuItem("MyMenu/Test ^g")]
// shift + ←
[MenuItem("MyMenu/Test #LEFT")]
MenuCommand
当添加一个新的菜单项到Inspector中(使用 “CONTEXT/Component”),获取一个真实组件的引用也是有必要的
[MenuItem("CONTEXT/Transform/Init")]
static void Test3(MenuCommand cmd) {
Transform trans = cmd.context as Transform;
Debug.Log(trans.name);
}
和ContextMenu很像,ContextMenu给指定的组件定义默认的上下文菜单项,然而使用MeneItem只是为了扩展现有的组件菜单
给方法添加右键菜单
public ContextMenu (string itemName, bool isValidateFunction, int priority);
//itemName 路径名
//isValidateFunction 有效验证
//priority 菜单栏排序
[ContextMenu("Test")]
public void Test() {
Debug.Log(name);
}
给字段添加右键菜单
public ContextMenuItemAttribute (string name, string function);
// name 上下文名字
// function 应调用的函数名字
[ContextMenuItem("Add HP", "AddHp")]
public int HP = 0;
void AddHp() {
HP++;
}
告知编辑器类该编辑器所针对的运行时类型。
[CustomEditor(Type inspectedType, bool editorForChildClasses)]
样例
[CustomEditor(typeof(ViewScript))] // 标记
public class ViewScriptEditor : Editor {
// 检视面板属性绘制
public override void OnInspectorGUI(){
base.OnInspectorGUI();
}
}
using System.Collections; using System.Collections.Generic; using UnityEditor; using UnityEngine; public class TestScriptableWizard : ScriptableWizard { public string s = "aaa"; public int i = 500; public Color color = Color.red; [MenuItem("TestMenu/MyScriptableWizard")] //弹出窗口调用 static void CreateWizard() { // 展示对话框 ScriptableWizard.DisplayWizard<TestScriptableWizard>("MyTestMenu", "Create", "other");// 设置标题,Create按钮的文本,other按钮的文本 Debug.Log("CreateWizard"); } //开启窗口或数据更新时调用 void OnWizardUpdate() { helpString = "帮助或说明……"; Debug.Log("OnWizardUpdate"); } //当用户按下"other"时被调用,保存设置但不关闭窗口 void OnWizardOtherButton() { Debug.Log("OnWizardOtherButton"); } //点击"Create"时调用,关闭窗口并保存设置 void OnWizardCreate() { Debug.Log("OnWizardCreate"); } // 当选择发生改变的时候调用 private void OnSelectionChange() { } }
方法 | 内容 |
---|---|
public void ShowNotification (GUIContent notification); | 在窗口上显示通知消息。与消息框或日志消息不同,通知会在一段时间后自动消失。 |
要继承EditorWindow
public class MyWindow : EditorWindow {
[MenuItem("Window/My_Window",false,-30)]
static void ShowMyWindow() {
// 获取Window,没有则创建
MyWindow window = EditorWindow.GetWindow<MyWindow>();
window.Show(); // 展示
}
}
函数 | 内容 |
---|---|
EditorWindow.GetWindow() | 返回当前屏幕上第一个 t 类型的 EditorWindow。如果没有,则创建并显示新窗口,然后返回其实例。 |
分为GUI,EditorGUI,GUILayout,EditorGUILayout
不加Layout的不会自带布局,要自己手动确认位置
EditorGUI只是GUI的一个扩展(但是只能用在Editor模式下)
Width,MinWidth,MaxWidth 绝对大小,最小,最大(高度同理)
GUIStyle:Box,Button,laybel
不建议,因为是共享的数据,保存在注册表中,而且里面还存有Unity自己的键值对,建议用PlayerPrefs
// 和PlayerPrefs差不多
EditorPrefs.SetInt(string key,int value);
...
SerializedObject 和 SerializedProperty 两个类能够以完全通用的方式编辑 Unity 对象上的可序列化字段。这些类可自动处理个别序列化字段的脏化,以便 Undo 系统处理这些字段,并在检视面板中绘制时针对预制件重载正确设置这些字段的样式
static class Example2
{
[MenuItem("Edit/Reset Selected Objects Position")]
static void ResetPosition()
{
var transforms = Selection.gameObjects.Select(go => go.transform).ToArray();
var so = new SerializedObject(transforms);
// you can Shift+Right Click on property names in the Inspector to see their paths
so.FindProperty("m_LocalPosition").vector3Value = Vector3.zero;
so.ApplyModifiedProperties();
}
}
函数 | 内容 |
---|---|
ApplyModifiedProperties | 应用属性修改 |
ApplyModifiedPropertiesWithoutUndo | 在不注册撤销操作的情况下应用属性修改 |
FindProperty | 按名称查找序列化属性 |
GetIterator | 获取第一个序列化字段(迭代器) |
这是SerializedObject中获取的属性字段
函数 | 内容 |
---|---|
objectReferenceValue | 对象属性的值(Object) |
stringValue | 字符串属性的值。 |
name | 属性名称 |
isArray | 是否是数组 |
arraySize | 数组的大小 |
type | 属性的类型名称 |
Next() | 移至下一个属性 |
NextVisible() | 移至下一个可见属性 |
Reset() | 移至对象的第一个属性。 |
PrefabUtility
函数 | 内容 |
---|---|
SaveAsPrefabAsset | 在给定路径上,从给定的游戏对象创建一个预制件资源 |
SaveAsPrefabAssetAndConnect | 在给定路径上,从给定的游戏对象创建一个预制件资源,同时会使游戏对象和预设体关联引用 |
ApplyPrefabInstance | 将预制件实例上的所有重载应用于其预制件资源;相当于检视面板上的Apply All |
获取从 T 类型派生的类型的集合。
通过此方法可以快速访问 Unity 域程序集中派生自特定类或实现特定接口的所有类。基类或接口可为通用类型。
TypeCache.GetTypesDerivedFrom(Type parentType);
获取用 T 属性标记的方法的集合。
通过此方法可以快速访问从 Unity 域程序集加载并用特定属性标记的所有方法。结果中还包含用指定属性的上级标记的方法。
TypeCache.GetMethodsWithAttribute(Type attrType);
AssetDatabase 接口仅在编辑器中可用,它仅适用于放置在 Editor 文件夹中的脚本
函数 | 内容 |
---|---|
SaveAssets() | 将所有未保存的资源更改写入磁盘 |
.Refresh() | 刷新导入所有更改的资源 |
.FindAssets() | 使用搜索筛选器字符串搜索资源数据库,返回该资源的GUID(查找资源包括文件夹,文件)(后续有解释) |
.GUIDToAssetPath() | 通过资源GUID获取资源路径,返回相对于项目文件夹的路径 |
.GUIDFromAssetPath | 获取 path下资源的 GUID |
AssetDatabase.FindAssets(string filter[, string[] searchInFolders]);
案例
AssetDatabase.FindAssets("A"); //会筛选名称带有A的;eg。AXXX XXAXX
AssetDatabase.FindAssets("A B C"); // 多值匹配(与顺序无关),名称要同时满足有A、B、C
AssetDatabase.FindAssets("l:Field XXX"); // 标签匹配,同时可以在后续添加筛选名称
AssetDatabase.FindAssets("t:texture2D XXX"); // 类型匹配,同时可以在后续添加筛选名称
让您可以针对要执行更改的特定对象注册撤销操作。
要写在要改动之前
函数 | 内容 |
---|---|
RecordObject | 记录执行函数调用之后对象所做的任何更改;使用这一函数可以记录几乎所有属性的更改(有解释) |
DestroyObjectImmediate | 销毁对象并记录撤销操作,以便能够重新创建该对象。(解释) |
AddComponent | 记录新添加的组件 |
RegisterCompleteObjectUndo | 记录创建新的游戏对象 |
SetTransformParent | 记录更改变换组件的父子化 |
Undo.RecordObject (Object objectToUndo, string name);
无法使用这一函数记录变换组件的父项、AddComponent 和对象销毁,应该使用专用函数来记录。
DestroyObjectImmediate (Object objectToUndo);
名称 | 内容 |
---|---|
objectToUndo | 要销毁的对象。 |
访问编辑器中的选择。
列出常用的,更多看API
静态变量、函数 | 内容 |
---|---|
activeGameObject | 返回处于活动状态的游戏对象。(显示在检视面板中的对象)它还将返回可能为预制件或不可修改对象的游戏对象(当然除了获取也可以设置) |
activeObject | 返回实际对象选择。包括预制件、不可修改的对象。 |
activeTransform | 返回处于活动状态的变换。(显示在检视面板中的变换)。此函数绝不会返回预制件或不可修改的对象。 |
selectionChanged | 当前活动/所选项发生更改时触发的委托回调。 |
assetGUIDs | 返回所选资源的 GUID。在处理资源选择时,建议使用此属性,因为它还可以处理是否在 Project Browser(处于双列模式)的第一列中选择了文件夹。 |
函数 | 内容 |
---|---|
.SetDirty(Object target); | 将目标标记为脏数据 |
.ClearDirty(Object target); | 清除脏标记 |
.DisplayProgressBar(string title, string info, float progress); | 显示或者更新一个进度条 |
.ClearProgressBar() | 移除进度条,Diaplay后不会自动关闭,需要手动调用这个 |
主应用程序类,和Application不一样
函数 | 内容 |
---|---|
EnterPlaymode() | 将编辑器切换为运行模式。等同于将EditorApplication.isPlaying设置为 true |
ExitPlaymode() | 将编辑器切换为编辑模式。等同于将EditorApplication.isPlaying设置为 false |
OpenProject() | 打开某个项目,具体到项目路径(即该项目Assets前一级) |
using UnityEditor.Callbacks
[DidReloadScripts]
static void Callback(){
......
}
例子:获取构建项目的所有场景,并且以下拉框的形式出现在检视面板
SceneNameAttribute
public class SceneNameAttribute : PropertyAttribute {
}
SceneNameDrawer
using UnityEditor; using UnityEngine; [CustomPropertyDrawer(typeof(SceneNameAttribute))] public class SceneNameDrawer : PropertyDrawer { int sceneIndex = -1; GUIContent[] sceneNames; readonly string[] scenePathSplit = { "/", ".unity" }; /// <summary> /// GUI的绘制 /// </summary> /// <param name="position">用于绘制的位置</param> /// <param name="property">用来描述当前选项的容器</param> /// <param name="label">此属性的标签</param> public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { if (EditorBuildSettings.scenes.Length == 0) return; //在buildsetting中没有场景 // 初始化【获取所有场景名字,并构建成GUIContent容器 if (sceneIndex == -1) { GetSceneNamesArray(property); } int oldindex = sceneIndex; sceneIndex = EditorGUI.Popup(position,label, sceneIndex, sceneNames); // 如果菜单选择的和之前不一致需要更新显示的名字 if (oldindex != sceneIndex) { property.stringValue = sceneNames[sceneIndex].text; } } /// <summary> /// 获取所有场景名字数组 /// </summary> /// <param name="property"></param> private void GetSceneNamesArray(SerializedProperty property) { var scenes = EditorBuildSettings.scenes; // 获取到构建设置中的所有场景 // 初始化数组 sceneNames = new GUIContent[scenes.Length]; // 获取场景的名字【切割】,并构建所有的GUIContent元素 for (int i = 0; i < scenes.Length; i++) { string path = scenes[i].path; // 规定切割的内容,移除那些空的内容 string[] splitPath = path.Split(scenePathSplit, System.StringSplitOptions.RemoveEmptyEntries); string sceneName = ""; if (splitPath.Length > 0) { sceneName = splitPath[splitPath.Length - 1]; } else { sceneName = "(Delete Scene)"; } sceneNames[i] = new GUIContent(sceneName); } // 没有场景 if (scenes.Length == 0) { sceneNames = new[] { new GUIContent("Check Your Build Setting") }; } // 如果当前属性的内容不为空的 if (!string.IsNullOrEmpty(property.stringValue)) { bool nameFound = false; // 检测填写的内容是否存在【寻找名字】 for (int i = 0; i < sceneNames.Length; i++) { if (sceneNames[i].text == property.stringValue) { sceneIndex = i; nameFound = true; break; } } if (!nameFound) sceneIndex = 0; } else { // 默认第一个 sceneIndex = 0; } // 属性内容为选择的场景名字 property.stringValue = sceneNames[sceneIndex].text; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。