Unity 游戏框架搭建 2019 (二十三、二十四) 备份与版本号&危险的操作

先列出上一篇的总结:

  1. 要做的事情:

    • 备份:导出文件,并取一个合理的名字。
  2. 遗留问题:
    • 第八个示例与之前的示例代码重复,功能重复。
  3. 约定和规则:
    • 每个示例在 QFramework 目录下创建一个文件夹,文件夹的格式是: 数字.示例的功能
    • 每个示例写一个脚本,脚本中包含可复用的静态方法和 MenuItem 方法。
    • 每写一个示例进行一次导出,导出的文件名后边加上日期和时间,这个功能已经在导出功能里内置了。
  4. 示例分类:
    1. 知识学习&收集

      • API 收集
      • C# 语法实践
    2. 库本身的功能
      • 规则实现
      • 使用流程提供及优化
      • 效率提升(编码体验、逻辑复用)
      • 项目实用工具收集

我们先解决第一个问题,备份问题。

文件命名

导出文件很容易,但是文件的名字就比较有讲究了。现在我们的库呢第一次进行比较大的整理,未来说不定有很多次这样的整理。所以文件命名应该能够体现库的某一个阶段。

我们目前的命名规是 QFramework_日期_时,这种命名能够体现库的某个时间点,从而我们能够在多个文件之间找到最后一次更新的库。但是这样还不够。如果现在想找到第一篇文章的库,那要去找到第一篇文章写的时间。找到这个库的难度会随着时间越来越困难。不过这种命名已经完成了它的使命,最起码从第一个示例到现在没出现太大的问题。

但是有新的要求了。因为示例的代码会被删除,这算是代码的比较大的变更了,而且看专栏的童鞋所在的阶段也不同,有的童鞋刚刚看第一篇而有的童鞋已经完结了。所以要考虑库的各个阶段。

如何表示库的某个阶段呢?

有一种比较好的方式,就是按照文章的标题命名,比如这篇文章之前的库名字为 QFramework_19_开始整理,或者按照最新的示例名字,比如 QFramwork_13 GameObject 显示、隐藏简化。但是这样的名字过了很久回过头来找文件还是会要凌乱好一会,所以并不合适。

比较合适的是用版本号,我们生活中使用的软件都有版本号,比如 Unity 5.6.5 或者 2017.2 等等。对于开发者来说版本号已经是比较熟悉的东西了。

使用版本号命名的文件格式为: QFramework_vX.Y.Z

X 是主版本号,用于不向前兼容的更新。

Y 是中间版本,用于可向前兼容的功能性更新。

Z 是小版本号,用于功能完善和 bug 修复的更新。

一般都是从 v0.1.1 这个版本开始发布的,但是这个版本呢叫做 mvp 版本,也就是最小可验证版本。我们的库还没有到这个阶段,而且版本号这个东西刚开始用,是用于方便自己记忆的,也是为了做一个备份而已,还不用发布给别人用。所以我们的备份版本为 v0.0.0 。

还有一点要注意的是,v0.x.y 这个阶段的版本可以不考虑向前兼容。但是如果已经 v0.1.1 了,就要发布出去了,也有用户在使用了,那就要尽可能要做到向前兼容。

向前兼容的意思是,用户升级版本不必更改 API 的使用。

开始备份

在上一小节得到了结论。

现在,我们要开始着手导出。使用导出工具导出文件,并手动把文件名字命名为 QFramework_v0.0.0。

这样备份就算完成了。

可以把它放到网盘或者硬盘里。这样就可以安心整理代码了。

小结

版本号算是约定和规则的内容。

危险的操作

今天开始,进行逐个示例的整理。

第一个示例

先看第一个。

#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"));
		}
	}
}

因为在第八个示例里给提取成方法了,所以这个示例可以直接删除了。

删除之后的文件结构如下图所示。

第二个示例

代码如下

#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 = "要复制的关键字";
		}
	}
}

这个也在第八个示例中提取成方法了,所以这部分也可以直接删了,

删除之后的文件结构如下图所示:

第三个示例

代码如下:

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");
		}
	}
}

这个示例是是原来示例一和示例二的结合,同样在第八个示例中提取成方法了,果断删。

第四个示例

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
	}
}

同理,果断删。

第五个示例

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
	}
}

同理,果断删。

第六个示例

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
	}
}

同理果断删

第七个示例

#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
	}
}

第七个示例是快捷键功能,不过我们没有在第八个示例中提取成方法,因为快捷键不可以复用。

而这个是我们目前导出功能的核心代码,所以比较重要,这个就不能删除了。

通过观察可知,MenuClicked 方法中的对 MenuItem "QFramework/6.MenuItem 复用" 的复用,已经失效了,因为第六个示例被我们删掉了。

不过没关系,我们在第八个示例中有提取成方法。而使用方法完成导出功能的代码如下:

		[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");
		}

不过在写第八个示例的时候还是在用 MenuItem 进行方法的调用,虽然那时候已经学习了调用 public 方法,但是由于 public 方法的运用没有那么纯熟,想不到是很正常的。但是现在不一样了,我们用 public 方法进行非常多的方法设计练习了,所以直接着手整理就好了。

整理后的第七个示例代码如下:

using System.IO;

#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()
		{
			var generatePackageName = PreviousFunctions.GenerateUnityPackageName();

			PreviousFunctions.ExportPackage("Assets/QFramework",generatePackageName + ".unitypackage");

			PreviousFunctions.OpenInFolder(Path.Combine(Application.dataPath, "../"));
		}
#endif
	}
}

这些方法都是自己实现的,调用起来比较亲切了吧?

等待编译之后,再按下快捷键 ctrl/cmd + e,就自动导出成功了,感受到满满的成就感。

不过命名方式还是 QFramework_日期_时,不过没关系,这不算真正的导出,只是测试而已,我们还没有整理结束。整理这个阶段虽然在文章中要写很久,但是实际过程中可能几分钟就整理完了。但是整理这个过程写文章很久的原因是,因为在整理的候笔者的内心戏份非常多,也就是思考经过会非常多。而笔者呢都要把它们展示出来,这样大家理解了这些,就不难自己再造个 QFramework 了甚至更好,而本系列专栏的亮点就是这个。

到此呢,我们成功了。

不过以上代码呢,还存在一些问题:

  1. 方法所在的类名比较奇怪,比如 GenerateUnityPackageName 和 ExportPackage 所在的类都是 PreviousFunctions,PreviousFunctions 意思是之前的方法。是为了配合示例的名字而起的。
  2. 菜单栏的显示顺序问题,目前菜单栏的显示顺序有点混乱,如下。

这个问题存在了好久了,不过没办法,因为一到七个示例已经写好了,当时没办法更改,在整理阶段是改掉这个问题的比较好的时机。

因为在本篇文章的开头,有说过我们一个一个示例进行整理,所以这两个问题,我们先记录下来,等每个示例都整理了一遍之后,再看看如何解决。

除了以上存在的这两个问题,我们还做了一个比较危险的操作,就是先删除了第六个示例,等到第七个示例的时候发现功能失效了,还好在第八个示例中我们有相同的功能实现,否则就要去靠记忆力去恢复功能了,或者靠我们 v0.0.0 版本的备份进行恢复。这样会耗费我们额外的精力和时间,是很不值当的。

基于这个经验,我们在整理代码的时候,要优先确保功能是有效的,然后再进行一些变更或者删除的操作。

小结

把以上两个问题记录下来,我们的总结又可以更新了,更新后如下。

  1. 要做的事情:

    • (完成) 备份:导出文件,并取一个合理的名字。
  2. 遗留问题:
    • (完成一部分) 第八个示例与之前的示例代码重复,功能重复。
    • 方法所在类的命名有问题。
    • 菜单栏显示顺序问题。
  3. 约定和规则:
    • 每个示例在 QFramework 目录下创建一个文件夹,文件夹的格式是: 数字.示例的功能
    • 每个示例写一个脚本,脚本中包含可复用的静态方法和 MenuItem 方法。
    • 每写一个示例进行一次导出,导出的文件名后边加上日期和时间,这个功能已经在导出功能里内置了。
    • 每次有 API 变更的时候做一次备份,备份的名字采用 QFramework_vX.Y.Z 格式。
    • 每次进行整理的时候要确保是在功能有效的情况下进行删除和变更。
  4. 示例分类:
    1. 知识学习&收集

      • API 收集
      • C# 语法实践
    2. 库本身的功能
      • 规则实现
      • 使用流程提供及优化
      • 效率提升(编码体验、逻辑复用)
      • 项目实用工具收集

除了更新了两个问题以外,又在约定和规则中增加了关于备份的规则,描述得很清楚了,这里不多说了。

今天的内容就这些,拜拜~

转载请注明地址:凉鞋的笔记:liangxiegame.com

更多内容

原文地址:https://www.cnblogs.com/liangxiegame/p/12665002.html

时间: 2024-10-06 15:35:51

Unity 游戏框架搭建 2019 (二十三、二十四) 备份与版本号&危险的操作的相关文章

Unity 游戏框架搭建 2019 (九~十二) 第一章小结&第二章简介&第八个示例

第一章小结 为了强化教程的重点,会在合适的时候进行总结与快速复习. 第二章 简介 在第一章我们做了知识库的准备,从而让我们更高效地收集示例. 在第二章,我们就用准备好的导出工具试着收集几个示例,这些示例中有的是我们后续库的基础工具,也有的是在项目中非常实用的小工具,还有一些示例是实践了在框架搭建方向上非常重要的 C# 语法知识. 第二章大纲如下. 第八个示例(一) 在之前,我们完成了一个导出的功能.但是在完成这个功能的过程中,我们也遇到了一些问题.我们回忆一下,在<MenuItem 复用>的这

Unity 游戏框架搭建 2019 (十三~十五) 接下来要学什么?&amp; 第九个示例

在之前的两篇中,我们使用 public 静态方法对之前的内容进行了一个抽取,有了 public 静态方法这个工具,我们的学习行为也发生了一点变化. 在没使用 public 关键字之前呢,每一个示例仅仅是一个知识的记录作用.而我们用了 public 关键字之后,我们可以把知识作为一个可以复用的方法.但是呢,这样就有了一个顺序的问题. 我们是先写方法在写 MenuItem?还是先写 MenuItem 还是在写方法? 笔者给出的答案是,在学习新的 API 或者新的知识点的时候建议先写 MenuItem

Unity 游戏框架搭建 2019 (五) 打开所在文件夹

在上一篇中我们搞定了直接导出的功能,这算是一个巨大的进步了.那么在这篇我们再接着往下分析. 这样我们目前的导出步骤为: 点击菜单栏 QFramework/4.导出 UnityPackage. 我们是不是没有可以优化的空间了? 对于导出步骤的数量来说,确实没有了.只需要一步就可以导出了.但是从一个所花费的时间角度来讲其实还有空间的.也就是说,我们还可以节省时间. 我们跳出导出步骤这个角度,而是思考下导出之后我们做了什么事情? 答案是:打开 unitypackage 所在的文件夹. 这步其实也比较耗

Unity 游戏框架搭建 2018(八)小结

Unity 游戏框架搭建 2018,是笔者在 gitchat 平台发布的 2018 年版本的框架搭建. 在 2018 年的时候 QFramework 已经集成了 UI Kit 和 Res Kit 这两个强大且好用的套件. 可以说 框架搭建 2018 版本是 对 2017 年版本的一个补充,主要补充的内容这是 UI Kit.Res Kit.和一个关于变量命名的讨论. 而在 2018 年,笔者首次发表了对变量命名的一个看法,其实在这一年,笔者从变量的命名研究中收益颇多,远大于 UI Kit 和 Re

Unity 游戏框架搭建 (二十一) 使用对象池时的一些细节

上篇文章使用SafeObjectPool实现了一个简单的Msg类.代码如下: class Msg : IPoolAble,IPoolType { #region IPoolAble 实现 public void OnRecycled() { Log.I("OnRecycled"); } public bool IsRecycled { get; set; } #endregion #region IPoolType 实现 public static Msg Allocate() { r

Unity游戏框架搭建 (一) 概述

??为了重构手头的一款项目,翻出来当时未接触Unity时候收藏的视频<Unity项目架构设计与开发管理>,对于我这种初学者来说全是干货.简单的总结了一下,以后慢慢提炼. 关于Unity的架构有如下几种常用的方式. 1.EmptyGO: ??在Hierarchy上创建一个空的GameObject,然后挂上所有与GameObject无关的逻辑控制的脚本.使用GameObject.Find()访问对象数据. 缺点:逻辑代码散落在各处,不适合大型项目. 2.Simple GameManager: ??

Cocos2d-x项目的游戏框架搭建

本篇所用的Cocos2d-x版本为:Cocos2d-x 3.2 Cocos2d-x项目的游戏框架搭建 游戏与应用项目其实差别不是很大,甚至有许多地方都是一样的,无非侧重点不同,手机游戏更侧重于用户的体验,更加的娱乐化.情感化.让玩家感觉“爽”.而手机应用更侧重于简单.明了,优先完成业务为重. 在以Cocos2d-x引擎为基础上,其实我们要做的准备工作还是很多的: 一.分析项目 首先,我们要知道,我们这个游戏是什么样类型的游戏,游戏机制是什么,按照目前市场上来说可以分成如下类型与机制: 1. 游戏

中文数字转换成阿拉伯数字(一千二百三十四万五千六百七十八--&gt;12345678)

昨天老大问我又没有写过中文数字转换成阿拉伯数字,我说没有,我说那应该简单啊,就是将中文对应的数字换成阿拉伯数字就好了啊,比如一就换成1,二就换成2…十换成10.可是那么问题来了…… 一十二呢…不能是1102吧…这不就坑爹了吗?一百万呢………所有我苦苦思索,花费了我差不多半天的时间,终于写出了下面的程序. 1 public static void main(String[] args){ 2 3 Map<Character, String> numberMap = new HashMap<

“全栈2019”Java第五十四章:多态详解

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第五十四章:多态详解 下一章 "全栈2019"Java第五十五章:方法的静态绑定与动态绑定 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Java学习小组"