原文地址:http://www.manew.com/thread-90330-1-1.html
Unity编辑器最重要的一个性能就是它的高度可扩展性。你可以创建任何你能想像出来的工具,并把它集成到Unity的菜单来让你的团队成员快速使用。Unity已经发布了一个关于自定义菜单的基础的帖子,你可以在
这里找到它(但这不是前提需求)。
Unity关于菜单项的文档对学习扩展Unity菜单系统的基础很有用,但它没有给出关于何时使用每个菜单的指南。进一步说,许多菜单的特殊行为没有被很好的解释。
这篇文章我将更深入的解释如何扩展菜单系统,何时使用每种菜单类,在每个菜单背后隐藏着什么特殊行为。
**Overview 概览
**
**
所有可以在unity里扩展的菜单
这里是所有可以被轻松扩展的菜单的截图。这些菜单是:
顶部所有内建菜单(A,B,C和D)
Hierachy窗口(B)右键菜单
Project窗口(A)右键菜单
当查看一个GameObject(C)时的Inspector下的Add Component菜单。
新的自定义的菜单(E)
菜单项的基础介绍
Unity允许开发者添称为自定义菜单项的新条目到菜单栏上的所有菜单里。从自定义菜单项里能够调用任意静态方法,所以你能在方法里做的事就能从菜单去调用。你可以在菜单里创建任意数量的子菜单,或者扩展已经存在的菜单,如“Assets/’Create”。如果Unity默认菜单没有一个是适合的,你就能创建全新的菜单(在Assets、GameObject等的旁边)。
一个自定义新的菜单项的例子,自定义菜单项处在一个已经存在的菜单的子菜单下
每个菜单项也有几个可以自定义的属性。你可以指定自定义菜单项在每个菜单里的顺序(在限制之内),可以给每个菜单项一个快捷键,连接到验证方法来决定是否禁用这个菜单项。
****如何创建一个自定义的菜单栏**
**
为了给一个自定义的菜单项指定一个方法,你只需要给静态方法添加[MenuItem] 属性(attributes)(如果你不熟悉attributes参见
MSDN documentation)。方法的访问性(公有/私有)、返回类型和名称都无关紧要。MenuItem属性(attributes)在UnityEditor命名空间下,所以你需要包含这个命名空间并把脚本放到名为Editor的文件夹下。如果你不熟悉特殊文件夹命名的话,参见
Unity’s documentation 。
Basic Menu Items 基本的菜单项
[MenuItem]的基本实现:
· MenuItem(string path)
参数:
Path—为你的菜单项指定菜单和名字的字符串。Path参数的格式如下:“Root Menu/Sub Menu1/Sub Menu2/Item Name [可选的 快捷键]”。
MenuItem属性的用法例子:
[MenuItem (“Assets/Create/Create Scriptable Object”)]
Path参数的一些额外注意事项:
· 如果首个词是已经存在的菜单名字(“Assets”, “Window”等),你的菜单项将被添加到这个菜单下(除了Component,稍后详细介绍)
· 你必须指定一个根菜单和一个菜单项名字
· 允许在所有菜单名以及菜单项名字中出现空格
· 可以选择在项名字加空格后的地方指定一个按键来设置快捷键(参考Unity的脚本API的 快捷键)
这个例子代码在GameObject菜单创建了一个菜单项,在选中该项时会在场景中创建一个名为“RedBlue GameObject”的新的游戏对象。
[MenuItem (“GameObject/Create RedBlue GameObject”)]
private static void CreateRedBlueGameObject ()
{
new GameObject (“RedBlue GameObject”);
}
高级菜单项用法
MenuItem属性的另一个实现方法就是添加验证方法的连接以及指定你菜单项的排列顺序的功能。
· MenuItem(string path, bool isValidateFunction, int priority)
参数:
isValidateFunction— 当置为真,使得这个方法在相应的方法(另外一个有MenuItem标签的有相同路径的方法)可以运行前被调用。这个特性很有用,但有点超出了本文的范围,所以阅读此文来找出更多关于有效菜单项的东西。(http://unity3d.com/cn/learn/tutorials/topics/interface-essentials/unity-editor-extensions-menu-items)
Priority— 这个值指定菜单项出现在每个菜单中的顺序。
菜单项的排序需要一点猜测。Unity菜单的每个菜单项有一个未知的优先级,找到菜单项需要放置的地方是令人苦恼的。我分类了常见菜单优先级在这篇文章里。
****何时使用每个菜单****
因为没有限制怎样使用菜单,这取决于开发者了解每个菜单背后的意图。这部分将讨论每个菜单的作用以及何时使用。
A. Assets
Assets菜单包含创建或者修改工程内资源的方法。我知道这很明显。但是稍微不那么明显的是这个列表里的菜单项在你右击工程面板的时候也会出现。此外,如果你把菜单项放入Create子菜单下也同样如此。
Assets菜单里的菜单项出现的其他地方
应该使用Asset菜单的例子:
创建脚本对象——所以我们自定义的脚本对象可以通过Assets/Create子菜单来创建
重命名Spritesheet——右击一个有多个精灵的纹理,激活一个菜单项帮助快速重命名所有子精灵
B. GameObject
GameObject菜单包含与场景中游戏对象一起使用的方法。例如,创建一个新的游戏对象或者编辑一个已经存在的游戏对象。菜单的子项在你右击一个游戏对象的时候也会出现,点击Scene Hierarchy窗口下的Create也会出现。
为了使菜单里的菜单项能够通过右击和Create按钮访问,它们必须被放到一个现存的子菜单中,如2D Object或者UI。如果现有的子菜单不适合,就可以通过添加一个新的菜单项到右击菜单中,但要就优先级要低于50.这实在看起来太容易了,Unity也可能在未来对此做出更改。
注意,如果你的工具添加组件到游戏对象上,你应该选择使用Component菜单。
应该使用GameObject菜单的方法的例子:
· 创建任何预定义的游戏对象,比如一个预设的实例—比如你应该使用一个菜单项去在一个新场景里设置一个自定义的相机。
· 用预设替代选中对象—这个工具基本和Break Prefab Instance相反。
C. Component
Component菜单下的所有菜单项添加组件到选中的游戏对象上。Unity强制你不能添加带有[MenuItem]属性的菜单项到这个菜单下面。Unity添加一个不同的属性[AddComponentMenu]来代替,需要放置到一个继承自MonoBehavior类上。这个MonoBehavior类型的类在你选择相应的菜单项的时候就自动被添加。
用[AddComponentMenu]属性标记一个类将让它出现在顶端菜单栏和AddComponent(当你在浏览一个游戏对象Inspector面板下的组件的时候可以看见)的列表中。属性采用路径作为参数,路径可以被分解成子菜单项,跟普通的MenuItem属性一样。
这个菜单不能排序菜单项,然而你可以把元素添加到一个存在的子菜单中。
我们添加的自定义的菜单项在Component菜单中看起来是这样的:
D. Unity, File, Edit, Window, and Help
这几个很简单。这些菜单里的菜单项不会出现在Unity内的任何其他环境下的菜单里。在工具会打开一个新的窗口并且不适合任何其他菜单的时候,我选择放入Window菜单。Edit菜单下放置同时修改游戏对象和资源的工具,比如自定义的复制或者重命名。我也用Edit来展现一个自定义工具的持久化的设置,因为我把它们看做是Unity工程设置的一个扩展。
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsA9EE.tmp.jpg
E. New Menu Item
如果没有一个现存的菜单对你的工具的功能来说有意义,就可以创建一个自己的新的菜单。注意Unity并不推荐这样,由于资源在工程和团队之间的共享很容易导致菜单栏的混乱。我们避免创建新的菜单“Red Blue Games”以及希望工具总是根据功能分组。添加自定义的“Red Blue Games”菜单会引起在“Assets”中使用自定义工具和“Red Blue Games”的混淆。
****Sorting in Detail****排序的细节**
**
为你的菜单项找到想要的排序真的很痛苦。最快的排序方法就是不排序0.0,但有时真的想要把自己的菜单项放到菜单下的一个特定地点。下面就是你排序菜单项时需要了解的。
菜单项按优先级从低到高排列,子菜单中也是。根据调用顺序来分块。如果你的菜单项优先级上一个菜单项的优先级高11及以上,Unity将在这个菜单项之前创建一个分割线。自定义菜单项没有指定优先级的话就会默认指定优先级为1000。
为自定义子菜单组自身排序的优先级是有小技巧的(相对于菜单项来说)。子菜单组将在第一次被创建的时候根据自定义的菜单项的优先级来进行排序。所以,如果你在创建了一个新的自定义的优先级为900的菜单项(Item A)在一个子菜单(在Window菜单内)中,这个子菜单就会出现在Window菜单优先级为900的位置,它里面的第一个菜单项也是如此。这个子菜单下的新的优先级为911的项将会带有分割线的排在Item A项后面。
内建菜单项的排列顺序
这就是排列顺序的原理,但如果你真的想要去使用它,就必须去知道默认菜单项的排序。我弄了几个Unity原生菜单排序细节的截图,在Unity 5.3.3版本里。
“Undefined”指的是这些菜单项的排序没有一个特定的排序。这些菜单项似乎实际上都被看做是1000.
Asset菜单排序
****
Asset/Create菜单排序
GameObject菜单排序
记住GameObject菜单的优先级低于50的菜单项(和现存子菜单的菜单项)也会出现在Hierarchy视图的右键菜单中。你不能在这个菜单里创建分隔线。
Windows菜单排序
排序: File, Edit, Unity Menus
我将把File,Edit和Unity菜单作为练习,留给读者(做这些还要下点功夫)。你可以通过这个Unity反编译工程来照出一些默认排序信息,或者就随机排列你的菜单项(提示:你可以给一个功能加上若干个[MenuItem])。