zoukankan      html  css  js  c++  java
  • Unity 游戏框架搭建 2019 (三十六~三十八) partial与public

    在上一篇,我们把菜单的顺序从头到尾整理了一遍。在整理菜单顺序的过程中,记录了一个要做的事情。

    要做的事情:

    • (完成) 备份:导出文件,并取一个合理的名字。
    • 整理完菜单顺序后,学习新的知识,解决随着示例增多,可能出现类需要合并的问题。

    我们要学习新的知识,试着解决类的合并问题。首先我们来看下要合并的类是什么,在我们的示例中是 TransformSimplify,这个 TransformSimplify 是对 Transform API 的简化,而 Transform 有非常多的 API,那么以后肯定还是会给 TransformSimplify 添加方法的。

    而我们的示例是逐个写的,写了一个示例,发现要给 TransformSimplify 添加方法,再回头找 TransformSimplify 类,再更改,这样很不妥。因为如果更改了 TransformSimplify 这个类了,那么对应的此篇专栏的文章就会失效了。

    所以如果有一个方法能够解决这个问题就好了,在每个示例就可以为已经有的类添加方法,而不去动用以前的示例代码,等学习到一个阶段后进行整理的时候统一进行合并。有这样的东西嘛?

    有的,C# 有提供 partial 关键字。

    它可以让一个类在多个文件中实现。那我们就试着给 TransformSimplify 和 GameObject 应用 partial 关键字吧。

    TransformSimplify 在第五个示例,增加后的代码如下:

    #if UNITY_EDITOR
    using UnityEngine;
    using UnityEditor;
    #endif
    
    namespace QFramework
    {
    	public partial class TransformSimplify
    	{
    #if UNITY_EDITOR
    		[MenuItem("QFramework/5.Transform API 简化/1.赋值优化", false, 5)]
    #endif
    		private static void MenuClicked1()
    		{
    			var transform = new GameObject("transform").transform;
    
    			SetLocalPosX(transform, 5.0f);
    			SetLocalPosY(transform, 5.0f);
    			SetLocalPosZ(transform, 5.0f);
    		}
    		
    #if UNITY_EDITOR
    		[MenuItem("QFramework/5.Transform API 简化/2.重置", false, 6)]
    #endif
    		private static void MenuClicked2()
    		{
    			var transform = new GameObject("transform").transform;
    
    			Identity(transform);
    		}
    
    		/// <summary>
    		/// 重置操作
    		/// </summary>
    		/// <param name="trans">Trans.</param>
    		public static void Identity(Transform trans)
    		{
    			trans.localPosition = Vector3.zero;
    			trans.localScale = Vector3.one;
    			trans.localRotation = Quaternion.identity;
    		}
    		
    		public static void SetLocalPosX(Transform transform, float x)
    		{
    			var localPos = transform.localPosition;
    			localPos.x = x;
    			transform.localPosition = localPos;
    		}
    		
    		public static void SetLocalPosY(Transform transform, float y)
    		{
    			var localPos = transform.localPosition;
    			localPos.y = y;
    			transform.localPosition = localPos;
    		}
    		
    		public static void SetLocalPosZ(Transform transform, float z)
    		{
    			var localPos = transform.localPosition;
    			localPos.z = z;
    			transform.localPosition = localPos;
    		}
    		
    		public static void SetLocalPosXY(Transform transform, float x, float y)
    		{
    			var localPos = transform.localPosition;
    			localPos.x = x;
    			localPos.y = y;
    			transform.localPosition = localPos;
    		}
    		
    		public static void SetLocalPosXZ(Transform transform, float x, float z)
    		{
    			var localPos = transform.localPosition;
    			localPos.x = x;
    			localPos.z = z;
    			transform.localPosition = localPos;
    		}
    		
    		public static void SetLocalPosYZ(Transform transform, float y, float z)
    		{
    			var localPos = transform.localPosition;
    			localPos.y = y;
    			localPos.z = z;
    			transform.localPosition = localPos;
    		}
    	}
    }
    

    GameObjectSimplify 在第七个示例,增加 partial 之后代码如下:

    #if UNITY_EDITOR
    using UnityEditor;
    #endif
     
    using UnityEngine;
    
    namespace QFramework
    {
        public partial class GameObjectSimplify
        {
            public static void Show(GameObject gameObj)
            {
                gameObj.SetActive(true);
            }
    
            public static void Hide(GameObject gameObj)
            {
                gameObj.SetActive(false);
            }
    
    #if UNITY_EDITOR
            [MenuItem("QFramework/7.GameObejct API 简化/显示、隐藏简化", false, 8)]
    #endif
            private static void MenuClicked()
            {
                var gameObject = new GameObject();
    
                Hide(gameObject);
            }
        }
    }
    

    增加之后呢,我们添加一个示例,用来验证 partial 关键字是否正确的。

    新的示例呢,是第八个示例。

    在示例中,分别为 TransformSimplify 和 GameObjectSimplify 增加一个方法。

    代码如下:

    #if UNITY_EDITOR
    using UnityEditor;
    #endif
     
    using UnityEngine;
    
    
    namespace QFramework
    {
        public partial class TransformSimplify
        {
            public static void AddChild(Transform transform, Transform childTrans)
            {
                childTrans.SetParent(transform);
            }
        }
    
        public partial class GameObjectSimplify
        {
            public static void Show(Transform transform)
            {
                transform.gameObject.SetActive(true);
            }
    
            public static void Hide(Transform transform)
            {
                transform.gameObject.SetActive(false);
            }
        }
        
        public class PartialKeyword
        {
    #if UNITY_EDITOR
            [MenuItem("QFramework/8.partial 关键字", false, 9)]
    #endif
            private static void MenuClicked()
            {
                var parentTrans = new GameObject("Parent").transform;
                var childTrans = new GameObject("Child").transform;
                
                TransformSimplify.AddChild(parentTrans,childTrans);
                GameObjectSimplify.Hide(childTrans);
    
            }
        }
    }
    

    执行的结果如下:006tNc79gy1fzfrjlpmilj30hw06c0sz.jpg

    菜单如下:
    006tNc79gy1fzfrjojvenj308f05bgnc.jpg

    目录如下:
    006tNc79gy1fzfrjrd85tj30gm0agjss.jpg

    学了这个 partial 之后,我们的合并问题就解决了。

    这样我们整理阶段要做的事情就做完了。

    要做的事情:

    • (完成) 备份:导出文件,并取一个合理的名字。
    • (完成) 整理完菜单顺序后,学习新的知识,解决随着示例增多,可能出现类需要合并的问题。

    partial 和 public 的合理使用以及整理完结篇

    在上一篇中,我们学习了新的知识 partial 关键字,那么我们什么时候该用 partial 呢?

    我们简单分析一下:

    • 像 GameObjectSimplify 和 TransformSimplify 都是很可能增长的类,所以自然就要用到了。
    • 而我们的 CommonUtil、EditorUtil、MathUtil 也是非常大的一个范畴,随着时间,要加的东西也会越来越多的。所以这两个类也要加上 partial。
    • 而 ResolutionCheck 类,目前只完成了比较常用的分辨率,未来随着时间肯定会遇到比较奇葩的分辨率的。所以 ResolutionCheck 也要加上 partial。
    • Exporter 呢,是专门为导出功能定制的,目前比较完善了。所以用不到 partial。而且 Exporter 里的 GeneratePackageName 事实上也不需要被其他的类调用了,所以它的访问权限也可以从 public 关键字也可以改成 private 了。

    基于以上,我们要给除了 Exporter 以外的所有的类都加上 partial,然后要把第一个示例的 Exporter.GeneratePackageName 的 public 关键字改成 private。

    到此呢,我们的整理就算真正的结束了。

    整理之后我们得到了几个类

    1. 简化类:GameObjectSimplify、TransformSimplify
    2. Util 类:CommonUtil、EditorUtil、MathUtil、ResolutionCheck
    3. 编辑器功能:Exporter

    这已经可以构成一个代码库了。

    复盘

    我们大体回忆下我们从第一篇到现在经历的阶段,大致可以分为如下两个阶段

    1. 学习收集示例阶段。
    2. 整理阶段。

    学习收集示例阶段

    其实我们可以理解为做项目或者做功能,为了做项目呢,往往我们会积累下来大量的代码。从而导致项目慢慢趋于混乱,直到无法在写下去(比如笔者也是写到某个示例的时候呢已经是瓶颈了,不知道写什么。

    整理阶段

    在整理阶段,会处理掉好多项目时间紧的时候没时间解决的代码设计问题。然后在整理阶段呢,也还会遇到很多意外的问题。不过经过整理之后,项目的结构会更加合理精简,再未来的一段时间内,可以让开发者愉快滴写功能,并且项目的发展也有了个方向(笔者也是通过这次整理,才知道了接下来的方向)。

    知识库 到 代码库

    而我们的知识库,一开始只是一个一个示例。而示例本身的存在,只是为了记录我们所接触的知识。但是随着我们的示例增加以及经验的提高,我们对示例库的要求就会变高,从只是为了记录知识到方法可复用、类名要合理。慢慢地就会变成一个代码库。

    那么大家还记得我们在第一篇定的小目标嘛? 打造自己的知识库,结果打造着打造着变成了个代码库。当然代码库本身还是有记录知识的作用的,只不过在记录知识的作用上还能提高我们的编码效率。之所以会这样是因为程序语言本身的存在就是为了提高人类生产力(编码效率),和传达信息的(记录知识)。

    提高编码效率,是因为它能够复用,能够记录知识的原因是,本身程序语言就是传达信息的,要不,它怎么叫语言呢?

    我们可以用日常用的语言写笔记,但是用程序语言一样也可以写笔记,同样笔记也是需要整理的。

    从知识库到代码库,我们也遇到了很多关键知识点,如下:

    1. public 关键字
    2. 类的第一作用
    3. partial 关键字

    在接触了这些关键知识点后,库的结构就会发生革命性的变化,结构会变得更合理清晰,且更容易扩展。而这些关键知识点,目前大多来自于 C# 语法,但是它们不仅仅是语法知识,而是能够帮助我们进行代码设计的知识,笔者把这些知识叫做设计工具。

    在代码中不管是设计一个庞大系统还是给一个项目做架构,或者仅仅是设计一个方法,都离不开这些设计工具,有了这些,可以让结构有更多地选择,更多地可能性。

    再次起航

    通过这次整理,我们收获了很多法宝,有了这些法宝我们有信心可以在接下来学习阶段中克服一切困难。如果实在克服不了,大不了我们再进行一次整理。

    说到整理,我们的库开发流程已经算是成型了。很简单,流程如下:

    • 学习收集示例
    • 整理
    • 学习收集示例
    • 整理
    • 学习收集示例

    如此往复,很快我们就能造出一个 QFramework,只不过要再多接触几个设计工具(C# 关键知识)。

    导出

    到此呢,我们的整理就真正完结了。我们好久没有进行导出了,在这篇我们就要进行一次导出,这次导出呢,要加上版本号。

    版本号为 v0.0.1 ,所以导出的文件名应该是 QFramework_v0.0.1。

    现在我们手头应该有两个版本的文件.

    • QFramework_v0.0.0: 整理之前的备份版本。
    • QFremework_v0.0.1: 整理完结后的版本。

    第三章 小与快速复习

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

    更多内容

  • 相关阅读:
    Codeforces 678E 状压DP
    Codeforces 667C DP
    POJ 3017 DP + 单调队列 + 堆
    Codeforces 1154F (DP)
    Codeforces 1154G 枚举
    Codeforces 1153D 树形DP
    Codeforces 1109E 线段树
    Codeforces 1109C 线段树
    Codeforces 1109D (树的计数问题)
    async/await
  • 原文地址:https://www.cnblogs.com/liangxiegame/p/12684802.html
Copyright © 2011-2022 走看看