角色移动与跳跃
双击打开SampleScene
创建一个Sprite——Square,命名为Ground,挂载Box Collider 2D,放在场景的下面,缩放至适合宽度
再创建一个Sprite,命名为Player,挂载Box Collider 2D和Rigidbody 2D,并且锁定Z旋转。
角色移动新建Scripts文件夹,从中新建一个脚本,命名为Player
12345678910111213141516171819using UnityEngine;namespace ShootingEditor2D{ public class Player : MonoBehaviour { Rigidbody2D m_rigidbody; private void Awake() { m_rigidbody = GetComponent<Rigidbody2D>(); } private void FixedUpdate() ...
概述与准备
概述应用篇是一个横板射击类 + 运行时关卡编辑器的一个游戏项目
关卡编辑器可以实现编辑游戏关卡,可以预览、保存、导出、甚至发布。
应用篇偏实践,会从纸上设计开始,展现思路,然后引入一个版本迭代的方法论,更好地管理开发过程。
模拟一个简单的游戏开发流程,即原型设计与机制打磨、量产、发布,介绍在这种流程下,如何使用这套架构。
准备
在UnityHub中新建一个2D项目,名字叫做ShootingEditor2D。
打开之前的工程,导出我们制作的Framework,在导出窗口中选择Framework文件夹,不勾选Include dependencies,然后保存在自己选定的文件夹当中,将package命名为“Framework_V0_0_1”。
将导出的包导入到新项目里面。
开发计划在开始一款游戏的时候,在初期阶段,需要去做游戏原型和基础的机制。
在这个阶段,可能美术资源还没给到,更多要做的是辅助游戏设计师去验证一些想法。(制作换皮或者抄袭的产品刚开始就是量产阶段,在此不多做讨论)
所以我们的射击游戏会有一个初始阶段,如下:
射击游戏开发计划:
初期阶段:机制打磨
这里的初期 ...
随机对话气泡(Bark)
新建场景——添加Dialogue Manager这个prefab——新建Dialogue Database。
创建对话点击Dialogue窗口中的Conversation选项卡,新建一个对话,将此对话命名为“Bark”
整体对话结构如下
Bark随机对话的内容必须和Start节点连接
创建人物在场景中新建一个Capsule,添加Dialogue Actor组件
在组件的Bark UI Settings——Bark UI里面,将Project窗口中的Assets——Plugins——Pixel Crushers——Dialogue System——Prefabs——Standard UI Prefabs——Templates——Bubble——Bubble Temples Standard Bark拉取进来
添加Bark On Idle组件
这样人物就能随机对话了
条件对话
设定变量首先新建一个新场景,然后像上一节一样将Dialogue Manager这个Prefab拖进Hierarchy里面
然后新建一个Dialogue Database,命名为Dialogue Database_2,在弹出的DIalogue窗口中点击打开Actor选项卡,添加一个Actor命名为Detective
选中这个选项卡中的Player,在inspector窗口中勾选“Use Display Name”,然后在DisPlay Name输入框中输入“Mr.Smith”。
然后选中Variables选项卡中,添加一个Boolean类型的变量,并命名为“At Work”,可以添加Description为“Player said he was at work”
编辑对话节点然后进入Conversations选项卡,点击加号新建一个Conversation,并在inspector窗口中将“Title”设置为Questioning,
我们选中Start节点,右键新建子节点,在子节点的DialogueText中,我们使用“var MarkUp Tag”来代替Palyer的名字。
输入“ ...
异步编程(asyn和await)
C#5.0引入了两个新关键词,async和await,大大简化了异步方法编程。
微软在不同时期使用的不同的异步模式,有3种:
异步模式
基于T事件的异步模式
基于Task的异步模式(TAP,Task Asynchronous Programming)
TAP是利用async和await关键字实现的,而且是微软极力推崇的一种异步编程方式。
注意!async和await关键字只是编译器功能。编译器会用Task类创建代码。如果不使用这两个关键词,C#4.0的Task类同样可以实现相同的功能,只是易读性和便利性差一些。
认识async和await使用async和await关键字编写异步代码,具有与同步代码相当的结构和简单性,并且摒弃了异步编程的复杂结构。
但是在理解上刚开始会很不习惯,而且会把一些情况想当然了。现在我们用一些示例慢慢开始理解它
一个简单的同步方法首先先写一个同步方法
1234567891011121314151617181920namespace AsyncandAwaitTest{ internal class Program { ...
C#集合——HashSet类
HashSet基础概念HashSet是System.Collection.Generic命名空间下的HashSet<T>类,是一个高性能且无序的集合
因为HashSet是无序的,所以它不能做排序操作,又不能像数组那样索引。在HashSet上只能使用foreach来进行迭代,而无法使用for循环。
HashSet中的元素不重复(可以存放单一的null),即具有元素唯一性,若向HashSet中插入重复元素,其内部会忽视此次操作,不会报出异常。因此若想拥有一个具有唯一值的集合,HashSet将会是一个具有超高检索性能的极佳选择。
1234567891011static void Main(string[] args){ HashSet<string> hashSet = new HashSet<string>(); hashSet.Add("A"); hashSet.Add("B"); hashSet.Add("C"); hashSet.Add(" ...
架构演化篇总结
架构层级以及职责Framework系统设计架构分为四层:
表现层:ViewControlller层
系统层:System层
数据层:Model层
工具层:Utility层
每个层级都有一些规则,如下:
层级
规则
表现层
获取System、获取Model、发送Command、监听Event
系统层
获取System、获取Model、获取Utility、监听、发送Event
数据层
获取Utility、发送Event
工具层
集成第三方库,或者封装API
除了四个层级,还有一个核心的概念是Command
Command
获取System、获取Model、获取Utility、发送Command、发送Event
这些信息其实都已经在框架的代码中以接口的形式说明了。
架构设计方法总览图包含整个项目的所有System、Model、Utility对象,以及大致的表现层流程图
功能实现图针对单个业务或者操作,绘制表现层对象或界面图、相关的System、Model、Utility对象、Command、Event的流向以及简单的引用关系。
贫血模型和充血模型以及最佳实践
贫血模型和充血模型对于接触后端的人说可能更熟悉
贫血模型先画一张图
这张图展现的就是表现层常用的逻辑,即查询逻辑。而且是一个贫血模型
我们有一个User对象,伪代码如下
12345678public class User{ public string Name {get;set;} public int Age {get;set;} public string Id {get;set;} public string NickName {get;set;} public float Weight {get;set;}}
总共有五个属性,但是在表现层的界面中,只需要显示三个属性:姓名、年龄、ID
我们在表现层使用GetUserById返回的是一整个User对象,这种数据流向模型叫做贫血模型
IUserModel的伪代码
123456789101112131415public interface IUserModel : IModel ...
纸上设计(四)总结
纸上设计的利弊纸上设计看起来容易做起来难,它就像良好的代码质量一样并不会对最终输出的程序有什么显性的帮助。
良好的代码质量只有在程序后期才能显现出来,前期会觉得为了质量会让编程更麻烦,我们所要做的就是让编写高质量的代码变成我们的习惯,写出又快又清晰的代码。比如将很多方法和实现,能用抽象接口描述出来的,就用接口描述出来。
同理,纸上设计,以及各种单元测试、重构、设计模式、设计原则也是一样的,纸上设计的本质就是UML图,但是UML图需要花费更多的时间去掌握,用例图、类图、时序图等,即使掌握了UML图,其实全部实践的机会也并不多,而纸上设计是UML的简化,它和我们目前的框架搭配得很好,我们只需要养成纸上设计的习惯就可以了。
为什么做纸上设计做项目能力的上限,就是能够应付多大的项目。如果能做一个项目在代码量10W行而没有崩溃,并且运转良好,那么再做个1W行左右的项目就会更容易,甚至能做出更精简的1W行项目。这就是做项目的能力。
做项目越大,里面的信息量也就越多,直接看代码就不可行,所以需要一个能描述项目结构的工具,这个工具就是UML,UML是很强大的项目描述工具,能够描述任何代码语言的逻辑,不 ...
纸上设计(三)全部功能完成
到目前为止我们实现的功能有
功能
规则
实现
最佳分数
存储并记录最佳分数
√
倒计时
游戏倒计时10秒
计分
点错一次扣5分,点对一次得10分,结束时倒计时每剩余1秒得10分
√
金币
每次点击正确的方块,有一定概率获得1~3金币
商店
游戏开始前可以在商店购买,能够抵消点击错误的次数
成就
百分成就、手残成就(分数为负数)、零失误成就、
重开
游戏结束后回到首页再来一次
在这一节我们实现所有的功能,
纸上设计首先整理思路,设计草图
然后可以做一个总览图
一般在交流沟通的时候,Command和Event都不会表示
针对每一个功能交互会单独画一张图,各个层级之间有连线,就像前两节中的那样
框架修改BindableProperty引入注销机制123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051using System;namespace FrameWorkDesign{ public c ...