标签:datetime 内部类 自己 静态 文件夹 一句话 click 整理 是什么
为了强化教程的重点,会在合适的时候进行总结与快速复习。
在第一章我们做了知识库的准备,从而让我们更高效地收集示例。
在第二章,我们就用准备好的导出工具试着收集几个示例,这些示例中有的是我们后续库的基础工具,也有的是在项目中非常实用的小工具,还有一些示例是实践了在框架搭建方向上非常重要的 C# 语法知识。
在之前,我们完成了一个导出的功能。但是在完成这个功能的过程中,我们也遇到了一些问题。我们回忆一下,在《MenuItem 复用》的这篇文章中,我们想对如下代码进行复用。
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
namespace QFramework
{
public class ExportUnityPackage : MonoBehaviour
{
#if UNITY_EDITOR
[MenuItem("QFramework/4.导出 UnityPackage")]
private static void MenuClicked()
{
var assetPathName = "Assets/QFramework";
var fileName = "QFramework_" + DateTime.Now.ToString("yyyyMMdd_hh") + ".unitypackage";
AssetDatabase.ExportPackage(assetPathName, fileName, ExportPackageOptions.Recurse);
}
#endif
}
}
这个方法被声明为 private 权限,所以是不可以被访问的。不过还好,MenuItem 可以复用,问题就勉强解决了。但是每次复用的时候要手打或复制一遍字符串未免也太麻烦了,而且也容易出错。那么还有其他的方式么?
这就是今天要解决的问题。当别的示例想调用以上的方法的时候,由于是 private 类型,所以只能通过 MenuItem 的方式进行调用,而 MenuItem 这种方式比较麻烦。
解决方案大家很容易就想到,把 private 改成 public 就行了。这样从达成代码复用这个目的的这个角度来说,问题是算是解决了,但是以笔者的经验来讲,这样还会有一些问题,就到这样就好。我们好好享受这个胜利的果实。
到这里如果有不知道 private 和 public 关键字的作用是什么的童鞋,那么笔者就简单提一句,使用 private 定义的方法只能在类的内部或者内部类中被调用,则不可以被子类和外部类调用,而使用 public 定义的方法,如果所在类也是 public 类型的,那么在任意地方可以被调用。
我们要怎么用这个 public 关键字呢?是在写示例的时候,仅仅把 private 改成 public 就行了嘛?有没有更好用的方法?
如果仅仅是把 private 改成 public 不是最好的方法,因为通过 MenuItem 修饰的方法,不能传参数,也没有返回值。不能传参或不能返回值的话,一个方法的使用就会受限。
所以笔者给出的方案是,再创建一个静态的 public 方法,而这个方法被 MenuItem 调用。这样的好处是,我们在创建一个方法的时候,可以好好地利用参数和返回值进行设计。
说了这么多,终于得到了一个明确的方案。我们来通过今天的第八个示例快速试一下。
第八个示例是什么呢,就是在第八个示例中,把所有的示例都提取成方法,并再次完成导出的功能。
首先第一个示例代码如下:
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using System;
namespace QFramework
{
public static class LogFileName
{
#if UNITY_EDITOR
[MenuItem("QFramework/1.生成 unitypackage 名字")]
#endif
private static void GenerateUnityPackageName()
{
Debug.Log("QFramework_" + DateTime.Now.ToString("yyyyMMdd_hh"));
}
}
}
这个示例的核心是 DateTime.Now.ToString() 这个代码。之所以是核心,是因为没用过它的人,第一次用会感觉很陌生,而且 Unity 和 C# 的 API 有那么多,怎么可能一个一个全部记住呢?所以就写了这样的一个示例,以便日后,要用的时候迅速翻阅这个代码就可以知道怎么用。随着时间,这个 API 用的次数会越来越多,慢慢自己就记住了。但是就算记住了,也有可能会忘的那一天,所以还有得让它在我们的库中存在。
OK,我们直接看提取后的代码。
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using System;
namespace QFramework
{
public class PreviousFunctions : MonoBehaviour
{
#if UNITY_EDITOR
[MenuItem("QFramework/8.总结之前的方法/1.获取文件名")]
#endif
private static void MenuClicked()
{
Debug.Log(GenerateUnityPackageName());
}
public static string GenerateUnityPackageName()
{
return "QFramework_" + DateTime.Now.ToString("yyyyMMdd_hh");
}
}
}
首先注意,MenuItem,由于第八个示例是有很多的东西,所以就又加了一级菜单。
点击以上菜单,执行结果正确。
在上一篇我们抽取了第一个示例的方法,我们在这篇在接着往下抽取。
先看第二个示例的代码。
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
namespace QFramework
{
public static class CopyText2Clipboard
{
#if UNITY_EDITOR
[MenuItem("QFramework/2.复制文本到剪切板")]
#endif
private static void CopyText()
{
GUIUtility.systemCopyBuffer = "要复制的关键字";
}
}
}
核心 API 是 GUIUtility.systemCopyBuffer,而后边的内容,应该是使用的时候自己填的。所以要创建一个 string 类型的参数,用来接收要复制的内容。抽取后的方法如下。
#if UNITY_EDITOR
[MenuItem("QFramework/8.总结之前的方法/2.复制文本到剪切板")]
#endif
private static void MenuClicked2()
{
CopyText("要复制的关键字");
}
public static void CopyText(string text)
{
GUIUtility.systemCopyBuffer = text;
}
我们接着看第三个示例
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
namespace QFramework
{
public class GenerateUnityPackageName2ClipBoard
{
#if UNITY_EDITOR
[MenuItem("QFramework/3.生成文件名到剪切板")]
#endif
private static void MenuClicked()
{
GUIUtility.systemCopyBuffer = "QFramework_" + DateTime.Now.ToString("yyyyMMdd_hh");
}
}
}
第三个示例和第一个和第二个示例重复了所以没有抽取的必要。不过,我们还是要实现与第三个 MenuItem 同等的功能的。
代码如下:
#if UNITY_EDITOR
[MenuItem("QFramework/8.总结之前的方法/3.生成文件名到剪切板")]
#endif
private static void MenuClicked3()
{
CopyText(GenerateUnityPackageName());
}
第四个示例代码如下:
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
namespace QFramework
{
public class ExportUnityPackage : MonoBehaviour
{
#if UNITY_EDITOR
[MenuItem("QFramework/4.导出 UnityPackage")]
private static void MenuClicked()
{
var assetPathName = "Assets/QFramework";
var fileName = "QFramework_" + DateTime.Now.ToString("yyyyMMdd_hh") + ".unitypackage";
AssetDatabase.ExportPackage(assetPathName, fileName, ExportPackageOptions.Recurse);
}
#endif
}
}
核心是 AssetDatabase.ExportPackage 这个 API。一般情况下 ExportPackageOptions 都是用 Recurse。所以只声明两个参数就好了。一个是 assetPathNam,一个是 fileName。抽取后的方法如下。
#if UNITY_EDITOR
[MenuItem("QFramework/8.总结之前的方法/4.导出 UnityPackage")]
private static void MenuClicked4()
{
ExportPackage("Assets/QFramework",GenerateUnityPackageName() + ".unitypackage");
}
#endif
public static void ExportPackage(string assetPathName,string fileName)
{
#if UNITY_EDITOR
AssetDatabase.ExportPackage(assetPathName, fileName, ExportPackageOptions.Recurse);
#endif
}
首先看代码:
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
namespace QFramework
{
public class OpenInFolder
{
#if UNITY_EDITOR
[MenuItem("QFramework/5.打开所在文件夹")]
private static void MenuClicked()
{
Application.OpenURL("file:///" + Application.dataPath);
}
#endif
}
}
核心的 API 就是 OpenURL,在打开文件夹的时候,一般路径的前缀是固定的。提取成如下:
#if UNITY_EDITOR
[MenuItem("QFramework/8.总结之前的方法/5.打开所在文件夹")]
private static void MenuClicked5()
{
OpenInFolder(Application.dataPath);
}
#endif
public static void OpenInFolder(string folderPath)
{
Application.OpenURL("file:///" + folderPath);
}
先看代码
using System.IO;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
namespace QFramework
{
public class ReuseMenuItem : MonoBehaviour
{
#if UNITY_EDITOR
[MenuItem("QFramework/6.MenuItem 复用")]
private static void MenuClicked()
{
EditorApplication.ExecuteMenuItem("QFramework/4.导出 UnityPackage");
Application.OpenURL("file:///" + Path.Combine(Application.dataPath, "../"));
}
#endif
}
}
核心 API 是 EditorApplication.ExecuteMenuItem。
提取方法后的代码如下。
#if UNITY_EDITOR
[MenuItem("QFramework/8.总结之前的方法/6.MenuItem 复用")]
private static void MenuClicked6()
{
CallMenuItem("QFramework/8.总结之前的方法/4.导出 UnityPackage");
OpenInFolder(Path.Combine(Application.dataPath, "../"));
}
public static void CallMenuItem(string menuPath)
{
EditorApplication.ExecuteMenuItem(menuPath);
}
#endif
先看代码:
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
namespace QFramework
{
public class CustomShortCut : MonoBehaviour
{
#if UNITY_EDITOR
[MenuItem("QFramework/7.自定义快捷键 %e")]
private static void MenuClicked()
{
EditorApplication.ExecuteMenuItem("QFramework/6.MenuItem 复用");
}
#endif
}
}
这个呢是自定义快捷键,所以目前没有办法复用,只能记在代码里了。在这里我们直接输出一句话就好。
代码如下:
#if UNITY_EDITOR
[MenuItem("QFramework/8.总结之前的方法/7.自定义快捷键")]
private static void MenuClicked7()
{
Debug.Log("%e 意思是快捷键 cmd/ctrl + e");
}
#endif
到此呢,第八个示例的代码算写完了。
如下:
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using System;
using System.IO;
namespace QFramework
{
public class PreviousFunctions : MonoBehaviour
{
#if UNITY_EDITOR
[MenuItem("QFramework/8.总结之前的方法/1.获取文件名")]
#endif
private static void MenuClicked()
{
Debug.Log(GenerateUnityPackageName());
}
public static string GenerateUnityPackageName()
{
return "QFramework_" + DateTime.Now.ToString("yyyyMMdd_hh");
}
#if UNITY_EDITOR
[MenuItem("QFramework/8.总结之前的方法/2.复制文本到剪切板")]
#endif
private static void MenuClicked2()
{
CopyText("要复制的关键字");
}
public static void CopyText(string text)
{
GUIUtility.systemCopyBuffer = text;
}
#if UNITY_EDITOR
[MenuItem("QFramework/8.总结之前的方法/3.生成文件名到剪切板")]
#endif
private static void MenuClicked3()
{
CopyText(GenerateUnityPackageName());
}
#if UNITY_EDITOR
[MenuItem("QFramework/8.总结之前的方法/4.导出 UnityPackage")]
private static void MenuClicked4()
{
ExportPackage("Assets/QFramework",GenerateUnityPackageName() + ".unitypackage");
}
#endif
public static void ExportPackage(string assetPathName,string fileName)
{
#if UNITY_EDITOR
AssetDatabase.ExportPackage(assetPathName, fileName, ExportPackageOptions.Recurse);
#endif
}
#if UNITY_EDITOR
[MenuItem("QFramework/8.总结之前的方法/5.打开所在文件夹")]
private static void MenuClicked5()
{
OpenInFolder(Application.dataPath);
}
#endif
public static void OpenInFolder(string folderPath)
{
Application.OpenURL("file:///" + folderPath);
}
#if UNITY_EDITOR
[MenuItem("QFramework/8.总结之前的方法/6.MenuItem 复用")]
private static void MenuClicked6()
{
CallMenuItem("QFramework/8.总结之前的方法/4.导出 UnityPackage");
OpenInFolder(Path.Combine(Application.dataPath, "../"));
}
public static void CallMenuItem(string menuPath)
{
EditorApplication.ExecuteMenuItem(menuPath);
}
#endif
#if UNITY_EDITOR
[MenuItem("QFramework/8.总结之前的方法/7.自定义快捷键")]
private static void MenuClicked7()
{
Debug.Log("%e 意思是快捷键 cmd/ctrl + e");
}
#endif
}
}
代码有点辣眼睛,因为宏定义太多了,并且 MenuItem 方法和 public 方法交叉使用,所以我们整理一下,整理后的代码如下。
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using System;
using System.IO;
namespace QFramework
{
public class PreviousFunctions : MonoBehaviour
{
public static string GenerateUnityPackageName()
{
return "QFramework_" + DateTime.Now.ToString("yyyyMMdd_hh");
}
public static void CopyText(string text)
{
GUIUtility.systemCopyBuffer = text;
}
public static void CallMenuItem(string menuPath)
{
EditorApplication.ExecuteMenuItem(menuPath);
}
public static void OpenInFolder(string folderPath)
{
Application.OpenURL("file:///" + folderPath);
}
#if UNITY_EDITOR
public static void ExportPackage(string assetPathName,string fileName)
{
AssetDatabase.ExportPackage(assetPathName, fileName, ExportPackageOptions.Recurse);
}
#endif
#if UNITY_EDITOR
[MenuItem("QFramework/8.总结之前的方法/1.获取文件名")]
private static void MenuClicked()
{
Debug.Log(GenerateUnityPackageName());
}
[MenuItem("QFramework/8.总结之前的方法/2.复制文本到剪切板")]
private static void MenuClicked2()
{
CopyText("要复制的关键字");
}
[MenuItem("QFramework/8.总结之前的方法/3.生成文件名到剪切板")]
private static void MenuClicked3()
{
CopyText(GenerateUnityPackageName());
}
[MenuItem("QFramework/8.总结之前的方法/4.导出 UnityPackage")]
private static void MenuClicked4()
{
ExportPackage("Assets/QFramework",GenerateUnityPackageName() + ".unitypackage");
}
[MenuItem("QFramework/8.总结之前的方法/5.打开所在文件夹")]
private static void MenuClicked5()
{
OpenInFolder(Application.dataPath);
}
[MenuItem("QFramework/8.总结之前的方法/6.MenuItem 复用")]
private static void MenuClicked6()
{
CallMenuItem("QFramework/8.总结之前的方法/4.导出 UnityPackage");
OpenInFolder(Path.Combine(Application.dataPath, "../"));
}
[MenuItem("QFramework/8.总结之前的方法/7.自定义快捷键")]
private static void MenuClicked7()
{
Debug.Log("%e 意思是快捷键 cmd/ctrl + e");
}
#endif
}
}
逐个执行菜单,运行结果全部正确。
到此呢,我们可以进行一次导出了。
ok,今天的内容就这些。
转载请注明地址:凉鞋的笔记:liangxiegame.com
QFramework 地址:https://github.com/liangxiegame/QFramework
QQ 交流群:623597263
Unity 进阶小班:
关注公众号:liangxiegame 获取第一时间更新通知及更多的免费内容。
Unity 游戏框架搭建 2019 (九~十二) 第一章小结&第二章简介&第八个示例
标签:datetime 内部类 自己 静态 文件夹 一句话 click 整理 是什么
原文地址:https://www.cnblogs.com/liangxiegame/p/12579604.html