在进行项目架构阶段,游戏框架可以解决一部分问题.剩下的架构问题还需要根据不同的项目解决.总之游戏框架是游戏架构的一部分. 关于锤子和钉子:   最近又拿起了<代码大全>和<暗时间>,想起来<暗时间>的作者维护了一个个人博客,就去逛一逛.   这几天一直琢磨一句话:手里拿着锤子看什么都像钉子.于是翻到了博客锤子和钉子.我的这个行为很好的阐述了什么叫:手里拿着锤子看什么都想钉子- -.   看完之后深度自省了一下- -   文章很有趣,推荐大家读下.   对于框架,用锤…
方法 使用自己的Yii2镜像作为基础 使用Yii2的Web框架搭建,为了节省搭建Yii2框架的时间,直接使用现有的Yii2项目,删除了业务相关的逻辑类,将这个代码库作为搭建微服务框架的基础,本身已经积累了大量的库和工具类:因为如果使用Yii2的话,还需要安装大量的其他库和工具类 集成APIGateway APP与服务的通信采用RestAPI的方式, 集成RPC 解决服务于服务之间的依赖问题,使用RPC进行非HTTP协议的远程调用…
第一步:1.新建项目 2.新建domain类库 3.新建Data类库 4.为上面的1.2.3添加实体框架nuget包.(可以右键管理nuget包来查找entityframework,当然也可以通过程序控制台) Install-Package Microsoft.AspNet.Identity.EntityFramework -Version 2.2.1 5.在Data类库中加入***Dbcontext文件.…
一.引入pom <dependency> <groupId>me.lovegao</groupId> <artifactId>gdao</artifactId> <version>0.0.2-SNAPSHOT</version> </dependency> 需要先将gdao项目(https://github.com/shuimutong/gdao.git)打包加到本地仓库. 0.0.2版本:tag:dev-1-…
初学java EE,虽然知道使用框架会使开发更加便捷高效,但是对于初学者来说,感到使用框架比较迷惑,尤其是各种jar包的引用.各种框架的配置.注解的使用等等. 最好的学习方法就是实践,于是下载了一个现成的DEMO,通过简单的修改先成功在自己电脑上跑起来,然后再逐个文件进行分析学习,最终才能从总体的高度上掌握框架的运行机制和配置方法,这样才能在实际运用中灵活配置,不会再局限于示例框架中. SSM框架搭建流程 SSM框架Web程序的流程 上面链接总结的流程很好,但是该流程没有加入DAO这一层,经过分…
背景: 前段时间用Xamarin.OSX开发一些工具,遇到了两个问题. QFramework的大部分的类耦合了Unity的API,这样导致不能在其他CLR平台使用QFramework. QFramework定义了太多了命名空间,如果使用vs for mac或者MonoDevelop开发项目很不方便,每次都要先using命名空间IDE才会提供代码提示,当然用Rider就没有这个问题. 基于以上几点进行了一次架构调整. 目前架构: 为了提升开发效率,命名空间全部统一为QFramework,而不是像以…
我们的项目开始立项的时候,最常见的一个情况就是:几个人的小团队,一开始什么也不做,就开始写代码,验证逻辑,游戏就开始写起来了.而公司的一些所谓的领导层面一开始就把游戏定义为我们要做一个大作.这个事情本身就是一个笑话,因为没有任何的规划和设计,我们就妄图写出一个杰出的作品出来是不现实的.Unity 在好用,那么以这个心态去做游戏,一定会写不出来好的游戏来.- 刘钢<Unity 项目架构设计与开发管理> 以上这段话说得很清楚了,就是做一个项目的时候一定要做规划和设计,当然这是从整个项目的角度来看,…
在上一篇我们收集了一个 屏幕分辨率检测的一个小工具.今天呢再往下接着探索. 问题 我们今天在接着探索.不管是写 UI 还是写 GamePlay,多多少少都需要操作 Transform. 而在笔者刚接触 Unity 的时候有一个非常不习惯的地方.就是对 transform 的位置.角度.缩放进行赋值. 比如,如果仅仅是对 transform.localPosition.x 进行赋值. 代码要这样写. var localPosition = transform.localPosition; loca…
昨天呢我们把第八个示例整理完了.整理之后学习了类的第一作用:方法的集合,还有 Obselete 这个 API.并且在进行整理的时候贯彻了我们新的约定和规则:先确保功能有效,再去做变更和删除. 今天我们在往下接着整理第九个示例 第九个示例 using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif namespace QFramework { public class ResolutionCheck { #if UNITY_EDITO…
在上一篇,我们把菜单的顺序从头到尾整理了一遍.在整理菜单顺序的过程中,记录了一个要做的事情. 要做的事情: (完成) 备份:导出文件,并取一个合理的名字. 整理完菜单顺序后,学习新的知识,解决随着示例增多,可能出现类需要合并的问题. 我们要学习新的知识,试着解决类的合并问题.首先我们来看下要合并的类是什么,在我们的示例中是 TransformSimplify,这个 TransformSimplify 是对 Transform API 的简化,而 Transform 有非常多的 API,那么以后肯…
在上一篇,我们接触了单例,使用单例解决了我们脚本之间访问的问题. 脚本之间访问其实有更好的方式. 我们先分下脚本访问脚本的几种形式. 第一种,A GameObject 是 B GameObject 的 Parent,或者是中间隔着几个层级的 Parent. 那这种情况下,如果 A 脚本想调用 B 脚本的方法,直接通过 transform.Find("XXX/YYY/ZZZ").GetComponent<B>().DoSomething() 就可以了. 但是如果是 B 脚本想…
  上一篇文章讲述了如何设计C#单例的模板.也随之抛出了问题: 如何设计接收MonoBehaviour生命周期的单例的模板? 如何设计? 先分析下需求:   1.约束脚本实例对象的个数.   2.约束GameObject的个数.   3.接收MonoBehaviour生命周期.   4.销毁单例和对应的GameObject.   首先,第一点,约束脚本实例对象的个数,这个在上一篇中已经实现了.   但是第二点,约束GameObject的个数,这个需求,还没有思路,只好在游戏运行时判断有多少个Ga…
  上一篇文章中说到的manager of managers,其中每个manager都是单例的实现,当然也可以使用静态类实现,但是相比于静态类的实现,单例的实现更为通用,可以适用大多数情况. 如何设计这个单例的模板?   先分析下需求,当设计一个manager时候,我们希望整个程序只有一个该manager对象实例,一般马上能想到的实现是这样的: public class XXXManager { private static XXXManager instance = null; private…
  为了重构手头的一款项目,翻出来当时未接触Unity时候收藏的视频<Unity项目架构设计与开发管理>,对于我这种初学者来说全是干货.简单的总结了一下,以后慢慢提炼. 关于Unity的架构有如下几种常用的方式. 1.EmptyGO:   在Hierarchy上创建一个空的GameObject,然后挂上所有与GameObject无关的逻辑控制的脚本.使用GameObject.Find()访问对象数据. 缺点:逻辑代码散落在各处,不适合大型项目. 2.Simple GameManager:   …
为什么用有限状态机?   之前做过一款跑酷游戏,跑酷角色有很多状态:跑.跳.二段跳.死亡等等.一开始是使用if/switch来切换状态,但是每次角色添加一个状态(提前没规划好),所有状态处理相关的代码就会指数级增长,那样就会嗅出代码的坏味道了.在这种处理状态并且状态数量不是特别多的情况下,自然就想到了引入状态机.优点:  1.使代码整洁,状态容易扩展和管理.  2.可复用.  3.还没想到.....缺点:  1.也没想到...... 什么是有限状态机?   解释不清楚,看了下百度百科.反正是一种…
什么是消息机制? 23333333,让我先笑一会. 为什么用消息机制?   三个字,解!!!!耦!!!!合!!!!. 我的框架中的消息机制用例: 1.接收者 ``` using UnityEngine; using System.Collections; using QFramework; /// /// 1.接收者需要实现IMsgReceiver接口. /// 2.使用this.RegisterLogicMsg注册消息和回调函数. /// public class Receiver : Mon…
本来这周想介绍一些框架中自认为比较好用的小工具的,但是发现很多小工具都依赖一个类----App. App类的职责: 1.接收Unity的生命周期事件. 2.做为游戏的入口. 3.一些框架级别的组件初始化. 本文只介绍App的职责2:做为游戏的入口. Why? 在我小时候做项目的时候,每次改一点点代码(或者不止一点点),要看下结果就要启动游戏->Loading界面->点击各种按钮->跳转到目标界面看结果或者Log之类的.一天如果10次这种行为会浪费很多时间,如果按照时薪算的话那就是....…
约定 还记得上版本的第二十四篇的约定嘛?现在出来履行啦~ 为什么要重制? 之前写的专栏都是按照心情写的,在最初的时候笔者什么都不懂,而且文章的发布是按照很随性的一个顺序.结果就是说,大家都看完了,都还对框架没有一个感觉,感觉很乱.而现在,经过两年多的摸索,笔者已经对框架的体系有了一个了解,所以希望再版一次此系列的专栏. 为什么不在原来的文章里直接修改呢? 在上一轮的专栏第二十四篇里有讲过过:虽然以前的内容过时了,但是这些专栏对笔者有很重要的意义,它们记录了笔者成长的一个经历,在评论区有着大家的支…
Unity 游戏框架搭建 2018 (二) 单例的模板与最佳实践 背景 很多开发者或者有经验的老手都会建议尽量不要用单例模式,这是有原因的. 单例模式是设计模式中最简单的也是大家通常最先接触的一种设计模式.在框架的设计中一些管理类或者系统类多多少少都会用到单例模式,比如 QFramework 中的 UIMgr,ResMgr 都是单例.当然在平时的游戏开发过程中也会用到单例模式,比如数据管理类,角色管理类等等,以上这些都是非常常见的使用单例的应用场景. 那么今天笔者想好好聊聊单例的使用上要注意的问…
在日常开发中,我们经常遇到或者写出这样的代码 var sTrAngeNamingVariable = "a variable"; #if UNITY_IOS || UNITY_ANDROID || UNITY_EDITOR sTrAngeNamingVariable = "a!value"; #else sTrAngeNamingVariable = "other value"; #endif 宏本身没有什么问题.但是 MonoDevelop I…
本篇本来是作为原来 优雅的QChain的第一篇的内容,但是QChain流产了,所以收录到了游戏框架搭建系列.本篇介绍如何实现GameObject的链式编程. 链式编程的实现技术之一是C#的静态扩展.静态扩展可以做到无需继承GameObject就可以为GameObject的对象添加成员方法.其实这么说不太严谨,但是看起来就是这样:) C# 静态扩展快速入门 首先我们要实现给GameObject添加一个DestroySelf方法.使用方式如下: gameObject.DestroySelf(); 贴…
之前的文章中介绍的Unity 游戏框架搭建 (二) 单例的模板和Unity 游戏框架搭建 (三) MonoBehaviour单例的模板有一些问题. 存在的问题: 只要继承了单例的模板就无法再继承其他的类. 虽然单例继承其他类是比较脏的设计,但是难免会遇到不得不继承的时候.没有最好的设计,只有最合适的设计. 解决方案: 首先实现单例的类从使用方式上应该不变,还是 XXX.Instance.ABCFunc() 之前的单利的模板代码如下所示: ``` using System; using Syste…
从框架搭建系列的第一篇文章开始到现在有四个多月时间了,这段时间对自己来说有很多的收获,好多小伙伴和前辈不管是在评论区还是私下里给出的建议非常有参考性,在此先谢过各位. 说到是一篇小节,先列出框架的概要图. 目前,图中除了UI模块和未支持的部分,都有相应的文章来介绍. 设计模式: Unity 游戏框架搭建 (二) 单例的模板Unity 游戏框架搭建 (三) MonoBehaviour单例的模板 事件: Unity 游戏框架搭建 (五) 简易消息机制 AI: Unity 游戏框架搭建 (四) 简易有…
为毛要实现这个工具? 在我小时候,每当游戏在真机运行时,我们看到的日志是这样的. 没高亮啊,还有乱七八糟的堆栈信息,好干扰日志查看,好影响心情. 还有就是必须始终连着usb线啊,我想要想躺着测试... 以上种种原因,QConsole诞生了. 如何使用? 使用方式和QLog一样,在初始化出调用,简单的一句. QConsole.Instance(); 就好了,使用之后效果是这样的. 在Editor模式下,F1控制开关. 在真机上需要在屏幕上同时按下五个手指就可以控制开关了.(本来考虑11个手指萌一下…
为毛要实现这个工具? 在我小时候,每当游戏到了测试阶段,交给QA测试,QA测试了一会儿拿着设备过来说游戏闪退了....当我拿到设备后测了好久Bug也没有复现,排查了好久也没有头绪,就算接了Bugly拿到的也只是闪退的异常信息,或者干脆拿不到.很抓狂,因为这个我是没少加班.所以当时想着解决下这个小小的痛点... 现在框架中的QLog: 怎么用呢?在初始化的地方调用这句话就够了. QLog.Instance (); 其实做成单例也没有必要.... 日志获取方法: PC端或者Mac端,日志存放在工程的…
前言 架构和框架这些概念听起来很遥远,让很多初学者不明觉厉.会产生"等自己技术牛逼了再去做架构或者搭建框架"这样的想法.在这里笔者可以很肯定地告诉大家,初学者是完全可以去做这些事情的. 初识架构和框架 架构和框架是非常接地气的,离我们其实并不遥远. 什么是架构? 架构是一个约定,一个规则,一个大家都懂得遵守的共识.那这是什么样的约定.什么样的规则.什么样的共识呢? 我以包为例,我经常出差,双肩背包里装了不少东西.笔记本电脑.电源.2 个上网卡.鼠标.USB 线.一盒大的名片.一盒小的名…
导出 UnityPackage 功能到这里要告一段落了,相信认真看的童鞋都有收获.笔者在写教程之前纠结了很久.到底是先给出一坨工具代码,然后再逐个讲解比较好,还是一篇一个知识点比较好.后来想通了.工具和知识点都要同时写.也就诞生了这个系列的教程,这对笔者来说是一个挑战. 在 框架搭建 2017 年版本,采用的就是一篇文章一个小工具.而到了 2018 年版本,自己的内容变多了,所以一篇文章会讲好多东西.大家读起来内容会比较深一点,一篇文章大概要读个半个小时.再后来觉得一篇文章读半个小时这件事对笔者…
第一章小结 为了强化教程的重点,会在合适的时候进行总结与快速复习. 第二章 简介 在第一章我们做了知识库的准备,从而让我们更高效地收集示例. 在第二章,我们就用准备好的导出工具试着收集几个示例,这些示例中有的是我们后续库的基础工具,也有的是在项目中非常实用的小工具,还有一些示例是实践了在框架搭建方向上非常重要的 C# 语法知识. 第二章大纲如下. 第八个示例(一) 在之前,我们完成了一个导出的功能.但是在完成这个功能的过程中,我们也遇到了一些问题.我们回忆一下,在<MenuItem 复用>的这…
在笔者刚做项目的时候,遇到了一个需求.第一个项目是一个跑酷游戏,而跑酷游戏是需要一条一条跑道拼接成的.每个跑道的长度是固定的,而怪物的出现位置也是在跑道上固定好的.那么怪物出现的概率决定一部分关卡的难度. 以上有点绕,其实就是,到某一个时刻,怪物是否要出现.而是否要出现是根据概率来决定的.如果一个怪物出现的概率是 100%,那么每次到达跑道固定的位置时候都要生成怪物.如果是 80% 那么就有百分之二十的几率不生成怪物. 那么如何去写这个逻辑呢? 我们先分析一下,我们要输入的是一个概率,而得出的结…
先列出上一篇的总结: 要做的事情: 备份:导出文件,并取一个合理的名字. 遗留问题: 第八个示例与之前的示例代码重复,功能重复. 约定和规则: 每个示例在 QFramework 目录下创建一个文件夹,文件夹的格式是: 数字.示例的功能 每个示例写一个脚本,脚本中包含可复用的静态方法和 MenuItem 方法. 每写一个示例进行一次导出,导出的文件名后边加上日期和时间,这个功能已经在导出功能里内置了. 示例分类: 知识学习&收集 API 收集 C# 语法实践 库本身的功能 规则实现 使用流程提供及…