ZFramework-构建框架雏形

本文介绍了如何在Unity2022.3.16LTS版本中使用Gitkraken进行版本管理,包括连接Gitee、创建Editor脚本和全局方法,如自动生成包名、复制文本到剪贴板、导出资源包等,以提升项目管理效率。
摘要由CSDN通过智能技术生成

Unity版本

  • 使用Unity2022.3.16f1 LTS 版本
  • 框架使用长期支持版均可

初始化项目

版本管理

  • 使用Git进行版本管理

使用Gitkraken图形化工具

连接Gitee

1.打开Gitkraken,然后找到设置中的SSH,如果之前没有生成,点击生成后,点击SSH Public Key右边的复制按钮
在这里插入图片描述
2. 打开Gitee设置,复制到箭头处,自定义SSH标识名称
在这里插入图片描述
3.在Gitkraken中选择克隆即可

框架雏形

  • 框架简单来说就是多个方便易用的工具代码集成在一起,能够更便利地解决实际问题的拥有一定结构的整体性代码。

基础目标

  • 首先完成版本导出功能,方便未来新增内容
  • 接下来拆分目标

了解Editor文件夹

  • 只涉及编辑器的代码可以放在Editor文件夹(unity资源包导出可以是只关于编辑器行为的,所以可以直接放入Editor文件夹)
  • Editor文件夹的代码会编译到Assembly-CSharp-Editor.dll中,它可以访问运行时DLL中的代码(也就是指具体的方法和变量),但是运行时DLL中的代码无法访问它,这是因为编辑模式下的代码不能在运行期间使用。
1.生成文件名:
  • 核心API:
    • DateTime.Now.ToString("yyyyMMdd_HH")
    • HH是指24小时制,hh是12小时显示
public static class GeneratePackageName 
{  
    [MenuItem("ZFramework/1.生成 UnityPackage 包的名字", false, 0)]  
    static void MenuClick()  
    {  
        Debug.Log("ZFramework_" + DateTime.Now.ToString("yyyyMMdd_HH"));  
    }  
}
2.复制字符串到剪贴板:
  • 核心API:
    • GUIUtility.systemCopyBuffer
public static class CpyText2ClipBoard  
{  
    [MenuItem("ZFramework/2.复制字符串到剪贴板", false, 1)]  
    static void MenuClick()  
    {  
        GUIUtility.systemCopyBuffer = "复制的文本";  
    }  
}
3.直接生成名称并复制到剪贴板:
public static class GenerateName2ClipBoard  
{  
    [MenuItem("ZFramework/3.生成包名到剪贴板", false, 2)]  
    static void Create()  
    {  
        var packageName = "ZFramework_" + DateTime.Now.ToString("yyyyMMdd_HH");  
        GUIUtility.systemCopyBuffer = packageName;  
    }  
}
4.Export资源包
  • 这个按钮在Asset菜单中,那么我们就可以调用代码进行(只要是能看到的一些操作或方法,很大概率有开发者可以调用的API)
  • AssetDatabase.ExportPackage()
public static class ExportZFramework  
{  
    [MenuItem(EditorGlobal.ZFrameworkMenuItemPath + "4.导出包到文件夹", false, 3)]  
    static void CreateExport()  
    {  
        // Debug.Log("成功使用全局字符串设置");  
  
        // 得到所有子文件夹的路径  
        var assetPathNameArray = AssetDatabase.GetSubFolders("Assets");  
        // 最终导出的包的文件名,要带上后缀拓展名 + ".unitypackage"        
        var filename = "ZFramework_" + DateTime.Now.ToString("yyyyMMdd_HH") + EditorGlobal.UnityPackageStr;  
        // 方法第三个参数为导出设置,默认Default是只打包当前文件夹的内容,Recurse是递归所有子列表打包,Interactive是异步打包,完成后显示打包位置  
        AssetDatabase.ExportPackage(assetPathNameArray, filename,  
            ExportPackageOptions.Recurse | ExportPackageOptions.Interactive);  
    }  
}
5.打开文件夹
  • Application.dataPath是项目Assets的绝对路径
  • Application.OpenURL(path); 可以打开对应的文件夹路径
[MenuItem(EditorGlobal.ZFrameworkMenuItemPath + "4.打开Application.dataPath", false, 3)]  
static void OpenFolder()  
{  
    // 得到绝对路径  
    var path = Application.dataPath;  
  
    Debug.Log("输出 Application.dataPath 的路径为: " + path);  
  
    // 也能打开网页  
    Application.OpenURL(path);  
}
6.MenuItem的复用
  • 通过一个MenuItem调用其他的MenuItem,可以是多个
public static class ReuseMenuItem  
{  
    [MenuItem(EditorGlobal.ZFrameworkMenuItemPath + "6.MenuItem的复用", false, 5)]  
    static void ReuseExecute()  
    {  
        Debug.Log("Unity编辑器的路径为: " + EditorApplication.applicationPath);  
        EditorApplication.ExecuteMenuItem(EditorGlobal.ZFrameworkMenuItemPath + "4.打开Application.dataPath");  
    }  
}
7.自定义快捷键
public static class CustomShortCut  
{  
    [MenuItem(EditorGlobal.ZFrameworkMenuItemPath + "7.自定义快捷键一键导出 %e", false, 6)]  
    static void ExecuteShortCut()  
    {  
        Debug.Log("快捷键输出: %e = Ctrl + E");  
        EditorApplication.ExecuteMenuItem(EditorGlobal.ZFrameworkMenuItemPath + "4.导出包到文件夹");  
    }  
}

第二部分

  • 整合第一阶段的方法
  • 目前第一阶段的方法是放到Editor文件夹,那么代表了这些方法都是不可以被逻辑部分调用的,但是其中有一部分方法在游戏逻辑中可能需要,避免重复编写。
  • 以及直接使用MenuItem的方法不能传参数,也不能有返回值,所以现在要提取具体方法。
  • 或者直接将所有C#脚本移出Editor文件夹,对每个UnityEditor的内容使用宏定义
    • #if UNITY_EDITOR 中间是要包裹的内容 #endif
  • 为了解决以上问题,得出最终方案:
    1. 首先把第一阶段的所有Editor方法,集成到一个C# 脚本文件中
    2. 该脚本文件命名为:FirstStageEditor, 表示第一阶段的Editor方法,然后设置全局常量路径字符串,避免打错字符
    3. 将之前的类名写成方法名,且方法名加上前缀ZEditor,表示这是ZFramework中Editor文件夹的方法
    4. 新建一个Editor文件夹之外的脚本文件,将具体方法实现从Editor文件夹中提取出来,供游戏逻辑中调用,可以写参数,可以有返回值
Editor脚本类,放在Editor脚本下
public static class FirstStageEditor
    {
        const string ZFrameworkMenuItemPath = "ZFramework/";

        [MenuItem(ZFrameworkMenuItemPath + "第一阶段方法集合/" + "1.生成 UnityPackage 包的名字", false, 0)]
        static void ZEditorGeneratePackageName()
        {
            Debug.Log(GlobalEditorFunction.GeneratePackageName());
        }

        [MenuItem(ZFrameworkMenuItemPath + "第一阶段方法集合/" + "2.复制包名到剪贴板", false, 1)]
        static void ZEditorCopyText2ClipBoard()
        {
            GlobalEditorFunction.GenerateNameCopy2ClipBoard();
        }

        [MenuItem(ZFrameworkMenuItemPath + "第一阶段方法集合/" + "3.打开 Application.dataPath 路径", false, 2)]
        static void ZEditorOpenFolder()
        {
            // 得到绝对路径
            var path = Application.dataPath;

            Debug.Log("输出 Application.dataPath 的路径为: " + path);

            GlobalEditorFunction.OpenFolder(path);
        }

        [MenuItem(ZFrameworkMenuItemPath + "第一阶段方法集合/" + "4.一键导出Unity包,含有MenuItem复用 %E", false, 3)]
        static void ZEditorExportZFrameworkPackage()
        {
            // 设置所有子文件夹的路径
            var folderList = new List<string>
            {
                "Assets/Editor",
                "Assets/Plugins",
                "Assets/ZFramework"
            };

            // 控制台同时输出一次包名
            EditorApplication.ExecuteMenuItem(ZFrameworkMenuItemPath + "第一阶段方法集合/" + "1.生成 UnityPackage 包的名字");

            // 最终导出包的名字,带上后缀拓展名
            var fileName = GlobalEditorFunction.GeneratePackageName() + ".unitypackage";

            // 方法第三个参数为导出设置,Default 是不递归子文件夹,Recurse 是向下递归所有子文件夹,Interactive 是异步打包并打开对应文件夹
            AssetDatabase.ExportPackage(folderList.ToArray(), fileName,
                ExportPackageOptions.Recurse | ExportPackageOptions.Interactive);
        }
    }
全局Editor方法类
  • 提取之前可能被游戏逻辑调用的方法
public static class GlobalEditorFunction
    {
        /// <summary>
        /// 生成 Unity 包的名称
        /// </summary>
        /// <returns>ZFramework前缀的包名</returns>
        public static string GeneratePackageName()
        {
            var packName = "ZFramework_" + DateTime.Now.ToString("yyyyMMdd_HH");
            return packName;
        }

        /// <summary>
        /// 把传入的字符串复制到剪贴板
        /// </summary>
        /// <param name="txt">传入的字符串</param>
        /// <returns>传入的字符串</returns>
        public static string CopyText2ClipBoard(string txt)
        {
            GUIUtility.systemCopyBuffer = txt;
            return txt;
        }

        /// <summary>
        /// 生成 Unity 包的名称,并立刻复制到剪贴板
        /// </summary>
        public static void GenerateNameCopy2ClipBoard()
        {
            CopyText2ClipBoard(GeneratePackageName());
        }

        /// <summary>
        /// 打开对应路径或网页
        /// </summary>
        /// <param name="path">绝对路径或网页</param>
        /// <returns>参数字符串返回</returns>
        public static string OpenFolder(string path)
        {
            // 也能打开网页
            Application.OpenURL(path);

            return path;
        }
    }

总结

  • 目前可以使用一键导出unitypackage包,或者使用快捷键迅速导出,可以方便之后积累自己的方法库,比如框架包导入实际项目,通过项目整合一些方法,然后写入框架文件夹,再一键导出,如此形成一个正向循环
  • 将引用了Unity.Editor的方法类,置于Editor文件夹中,可以避免打包错误,同时相比宏定义更加清晰,类具有单一职责原则,而且不容易出错,不存在忘记标识# if UNITY EDITOR的可能,在遵循该规范的前提下,会大大减少# if UNITY EDITOR 宏定义的使用(绝大部分应该可以分离开)
  • 17
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值