Unity 游戏框架搭建 2019 (三十、三十一) MenuItem 显示顺序问题 & 类的提取
在上一篇,我们得出了两个核心的学习思路:
- 根据问题去学习,并收集。
- 主动学习,并思考适用场景。
我们今天解决 MenuItem 显示顺序问题。
目前 MenuItem 显示如图所示:

我们来看下 MenuItem 这个属性构造的定义。

第二个参数是,是否是验证方法,目前不用理解,官网上默认是 false。
第三个参数,意思是优先级,表示 MenuItem 所在的显示顺序,数值越大越在底部。
我们先给第七个示例试一下。将代码改成如下:
using System.IO;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
namespace QFramework
{
public class CustomShortCut : MonoBehaviour
{
#if UNITY_EDITOR
[MenuItem("QFramework/7.自定义快捷键 %e",false,-10)]
private static void MenuClicked()
{
var generatePackageName = Exporter.GenerateUnityPackageName();
EditorUtil.ExportPackage("Assets/QFramework",generatePackageName + ".unitypackage");
EditorUtil.OpenInFolder(Path.Combine(Application.dataPath, "../"));
}
#endif
}
}
编译后观察菜单栏,结果如下图所示:

在最上方显示了。顺便我们把第七个示例的文件名和菜单名都改一下,都从 7.XXX 改成 1.XXX。
文件名如下:

菜单名代码如下:
using System.IO;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
namespace QFramework
{
public class CustomShortCut : MonoBehaviour
{
#if UNITY_EDITOR
[MenuItem("QFramework/1.自定义快捷键 %e",false,-10)]
private static void MenuClicked()
{
var generatePackageName = Exporter.GenerateUnityPackageName();
EditorUtil.ExportPackage("Assets/QFramework",generatePackageName + ".unitypackage");
EditorUtil.OpenInFolder(Path.Combine(Application.dataPath, "../"));
}
#endif
}
}
编译通过后菜单如下图所示:

其实菜单中的名字,还是不是合理,虽然这个示例我们是为了学习自定义快捷写下的,但是如果时间长了,我们看到上图的菜单栏还会懵一下。其实它的名字,应该叫做导出 UnityPackage。
我们就把菜单和目录名都改成这个 1. 导出 UnityPackage。具体怎么改大家应该知道了吧?
改完后的菜单如下:

目录如下:

在上面,我们搞定了调整菜单栏顺序的关键问题。
我们今天把剩下的顺序调整完,我们先整理第八个示例。
第八个示例
我们先看第八个示例的第一个 MenuItem,代码如下。
[MenuItem("QFramework/8.总结之前的方法/1.获取文件名")]
private static void MenuClicked()
{
Debug.Log(Exporter.GenerateUnityPackageName());
}
其中的 “QFramework/8.总结之前的方法/1.获取文件名” 我们可以改成 “QFramework/2.总结之前的方法/1.获取文件名”
不过这个总结的功能,对我们来说没有太大的作用了,因为我们在刚刚完成的第一个示例中,已经包含了 Exporter.GenerateUnityPackageName 的使用方式了。
第一个示例代码如下:
using System.IO;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
namespace QFramework
{
public class CustomShortCut : MonoBehaviour
{
#if UNITY_EDITOR
[MenuItem("QFramework/1.导出 UnityPackage %e",false,-10)]
private static void MenuClicked()
{
var generatePackageName = Exporter.GenerateUnityPackageName();
EditorUtil.ExportPackage("Assets/QFramework",generatePackageName + ".unitypackage");
EditorUtil.OpenInFolder(Path.Combine(Application.dataPath, "../"));
}
#endif
}
}
所以,我们删掉第八个示例中的这个 MenuItem 方法就好了。
再看第二个 MenuItem 代码如下:
[MenuItem("QFramework/8.总结之前的方法/2.复制文本到剪切板")]
private static void MenuClicked2()
{
CommonUtil.CopyText("要复制的关键字");
}
代码中 CommonUtil.CopyText 的使用,没有在第一个示例中包含。所以这个 MenuItem 要保留。
这个呢可以留着,我们对这段代码的 MenuItem 进行改进。改进后代码如下所示:
[MenuItem("QFramework/2.复制文本到剪切板",false,2)]
private static void MenuClicked2()
{
CommonUtil.CopyText("要复制的关键字");
}
代码中,菜单从二级变成,一级了,并且了添加了顺序,是第二个顺序。
等代码编译后,菜单展示如下所示:

顺序是正确的。但是第一个示例和第二个示例之间有一个分割线。为什么会有这个分割线呢?
有可能是因为 第一个示例,设置的顺序是 -10,而第二个示例设置的顺序是 2,中间相差太多了。
那么我们把第一个示例的顺序改成 1 试试。改动后的代码就不展示了。
改动之后,菜单如下图所示:

横线消失了,不过这个分割线算是意外的收获,我们可以好好利用它,比如用它来好好划分我们的菜单结构,题外话就先不说了。我们接着往下整理。
第二个示例的菜单整理好了,文件夹要怎么整理?现在这个示例的 MenuItem 方法在第八个示例中的 PreviousFuntions 里,而 示例的核心 API: CommonUtil.CopyText 也在第八个示例的文件里。
其实很简单,把这两部分提取出来就好了,将 MenuItem 示例方法写到 CommonUtil.CopyText 方法实现位置的上方。然后把 CommonUtil 这个类,单独从 PreviousFuctions.cs 这个文件中提取出来,放到第二个示例中。
代码如下:
CommonUtil.cs
using UnityEngine;
namespace QFramework
{
public class CommonUtil
{
#if UNITY_EDITOR
[UnityEditor.MenuItem("QFramework/2.复制文本到剪切板", false, 2)]
#endif
private static void MenuClicked2()
{
CopyText("要复制的关键字");
}
public static void CopyText(string text)
{
GUIUtility.systemCopyBuffer = text;
}
}
}
代码所在文件目录如下图:

那么第二个示例就算整理完成了。
单独把 CommonUtil 放在一个文件夹里的原因是与”方法所在类名”这个问题是一样的。都是方法所在的类不合理,所以会导致方法所在的类名比较奇怪。同理,类所在的文件夹不合理,所以导致菜单也不合理。因为我们的菜单的名字,和文件目录的名字是一一对应的。
虽然没有在文章中强调这一点,但是,笔者呢始终贯彻这个这个规则。
今天的内容就到这里,下一篇再见,拜拜~
转载请注明地址:凉鞋的笔记:liangxiegame.com
更多内容
QFramework 地址:https://github.com/liangxiegame/QFramework
QQ 交流群:623597263
Unity 进阶小班:
- 主要训练内容:
- 框架搭建训练(第一年)
- 跟着案例学 Shader(第一年)
- 副业的孵化(第二年、第三年)
- 权益、授课形式等具体详情请查看《小班产品手册》:https://liangxiegame.com/master/intro
- 主要训练内容:
关注公众号:liangxiegame 获取第一时间更新通知及更多的免费内容。

Unity 游戏框架搭建 2019 (三十、三十一) MenuItem 显示顺序问题 & 类的提取的更多相关文章
- Unity 游戏框架搭建 2019 (四十六) 简易消息机制 & 集成到 MonoBehaviourSimplify 里
在上一篇,我们接触了单例,使用单例解决了我们脚本之间访问的问题. 脚本之间访问其实有更好的方式. 我们先分下脚本访问脚本的几种形式. 第一种,A GameObject 是 B GameObject 的 ...
- Unity 游戏框架搭建 2019 (九~十二) 第一章小结&第二章简介&第八个示例
第一章小结 为了强化教程的重点,会在合适的时候进行总结与快速复习. 第二章 简介 在第一章我们做了知识库的准备,从而让我们更高效地收集示例. 在第二章,我们就用准备好的导出工具试着收集几个示例,这些示 ...
- Unity 游戏框架搭建 2019 (十三~十五) 接下来要学什么?& 第九个示例
在之前的两篇中,我们使用 public 静态方法对之前的内容进行了一个抽取,有了 public 静态方法这个工具,我们的学习行为也发生了一点变化. 在没使用 public 关键字之前呢,每一个示例仅仅 ...
- Unity 游戏框架搭建 2019 (二十五) 类的第一个作用 与 Obselete 属性
在上一篇我们整理到了第七个示例,我们今天再接着往下整理.我们来看第八个示例: #if UNITY_EDITOR using UnityEditor; #endif using UnityEngine; ...
- Unity 游戏框架搭建 2019 (二十六) 第一轮整理完结
昨天呢我们把第八个示例整理完了.整理之后学习了类的第一作用:方法的集合,还有 Obselete 这个 API.并且在进行整理的时候贯彻了我们新的约定和规则:先确保功能有效,再去做变更和删除. 今天我们 ...
- Unity 游戏框架搭建 2019 (四十八/四十九) MonoBehaviourSimplify 中的消息策略完善&关于发送事件的简单封装
MonoBehaviourSimplify 中的消息策略完善 在上一篇,笔者说,MonoBehaviourSimplify 中的消息策略还有一些小问题.我们在这篇试着解决一下. 先贴出来代码: usi ...
- Unity 游戏框架搭建 2019 (五十、五十一) 消息机制小结&MonoBehaviourSimplify 是框架?
我们花了 5 篇文章学习了消息机制的方方面面.并且完成了一个简易消息机制,之后集成到了我们的 MonoBehaviourSimplify 里. 现在 MonoBehaviourSimplify 有一点 ...
- Unity 游戏框架搭建 2019 (五十六/五十七) 需求分析-架构中最重要的一环&从 EmptyGO 到 Manager Of Managers
我们的项目开始立项的时候,最常见的一个情况就是:几个人的小团队,一开始什么也不做,就开始写代码,验证逻辑,游戏就开始写起来了.而公司的一些所谓的领导层面一开始就把游戏定义为我们要做一个大作.这个事情本 ...
- Unity 游戏框架搭建 2019 (二十九) 方法所在类命名问题诞生的原因
我们在整理阶段解决了一些意外的问题.但是这些问题仅仅只是被解决而已,我们并没有去思考过这些问题是为什么产生的?以及在以后我们如何去避免这些问题的产生? 方法所在类的命名问题,最后我们通过方法分类解决了 ...
随机推荐
- 答应我,不会这些概念,简历不要写 “熟悉” zookeeper
整理了一些Java方面的架构.面试资料(微服务.集群.分布式.中间件等),有需要的小伙伴可以关注公众号[程序员内点事],无套路自行领取 一口气说出 9种 分布式ID生成方式,面试官有点懵了 面试总被问 ...
- OpenCV-Python 直方图-1:查找、绘制和分析 | 二十六
目标 学会 使用OpenCV和Numpy函数查找直方图 使用OpenCV和Matplotlib函数绘制直方图 你将看到以下函数:cv.calcHist(),np.histogram()等. 理论 那么 ...
- win10系统 端口查看问题。
首先看图根据系统自带命令netsta介绍,说明显示协议系统信息和当前TCP/IP 网络连接. 使用范例: 打开命令提示符窗口,在这里输入命令netstat -an,然后按下回车键,这时可以显示出电脑中 ...
- 通过ISAPI http协议控制海康摄像头
一直用海康的SDK进行摄像头控制,但有时候非常不灵活,必须有X86的主机,在嵌入式上面就不行,通过写一个HTTPCLIENT可以通过ISAPI来控制海康的摄像头. 代码如下:git@github.co ...
- Spring核心组件知识梳理
Spring的一些概念和思想 Spring的核心:AOP.IOC. 简单点说,就是把对象交给Spring进行管理,通过面向切面编程来实现一些"模板式"的操作,使得程序员解放出来,可 ...
- Python第十二章-多进程和多线程02-多线程
接上一章,进程和线程之间可以存在哪些形式呢? 1 单进程单线程:一个人在一个桌子上吃菜. 2 单进程多线程:多个人在同一个桌子上一起吃菜. 3 多进程单线程:多个人每个人在自己的桌子上吃菜. 多线程的 ...
- WebView的基本使用及相关特性
WebView 是一个显示网页内容的组件,可以显示网络上的一些在线内容并且可以作为 Web 浏览器滚动显示的内容,它使用 WebKit作为渲染引擎来显示网页,里面包括放大.缩小.执行文本搜索等进行前后 ...
- E - E CodeForces - 1100E(拓扑排序 + 二分)
E - E CodeForces - 1100E 一个n个节点的有向图,节点标号从1到n,存在m条单向边.每条单向边有一个权值,代表翻转其方向所需的代价.求使图变成无环图,其中翻转的最大边权值最小的方 ...
- STM32F103ZET6 PWM输出
1.通用定时器的PWM功能 STM32F103ZET6有4个通用定时器,分别是TIM2.TIM3.TIM4.TIM5. 通用定时器由一个可编程预分频器驱动的16位自动装载计数器构成. 通用定时器的很多 ...
- Module Error (/index.js): error: 'HelloWorld' is defined but never used (no-unused-vars) at src\views\A.vue:9:8:
原因: