引言
今天给大家介绍的课程主要是游戏循环及实时模拟,内容包括游戏循环概述、《无尽之路》的实现以及支撑游戏的功能、机制与系统。
游戏循环概述
游戏程序的特点
常见的程序
- 命令行程序
- GUI 程序
- 操作系统服务
- WEB 服务
- MIS 系统
- 进销存系统
- 财务软件
- ERP
基本都是面向任务的被动处理,没有任务就可以休眠。
自动控制软件
- 设定值
- 调节器
- 自动调节
控制软件时刻从现场仪表或传感器获取当前状态,并通过自动调节使现场状态接近设定值。
主动处理,不能停止运行,停止意味着故障。
对于游戏而言其实是对真实世界的模拟,所以游戏程序除了被动响应,还需要主动运转:
- 必须有一个循环(也叫心跳)
- 循环驱动游戏世界的运转
- 循环驱动游戏里的 NPC 行为
- 循环实现游戏世界与玩家的交互
游戏引擎循环
游戏引擎循环中的一部分会驱动游戏逻辑的循环,而游戏逻辑循环则会有之前提到的这些物件的变化。
游戏循环
- 一般由引擎驱动,在每帧开始或结束进行游戏逻辑的处理
- 主要用来驱动游戏各子系统的运行
- 一般来说有两类风格
静态循环
依次调用各子系统的 Tick
- 优点:直白,容易理解
- 缺点:存在一定的空闲消耗
事件或消息驱动
类似 Windows 的消息循环机制
- 优点:通用的机制,主循环不依赖具体游戏系统,性能相对较好
- 缺点:缩写与调死比较复杂,代码不易理解
游戏循环子系统
游戏循环驱动各个子系统,包括:网络、场景、资源、游戏对象、AI、战斗、剧情、UI 等等。
游戏里的时间
绝对时间与相对时间
- Time scale 与游戏变速
- 加速播放(重演)
- 时间倒流(反演)
帧时间与实时时间
- 每帧更新一次的时间
- 实时时间
高精度时间
一般用在性能数据度量里,通常是硬件提供的机制。
垂直同步
早期显示器依靠电子枪逐行扫描,屏幕点依次显示,可能导致画面并不是同一帧的画面。现代显示器一般没有这种方式,在一些引擎中保留这种方式。
游戏循环的并行
前面我们默认游戏循环都是有限循环驱动的,但是现在我们还有多线程运行方式,所以我们可以在渲染循环里只做一次驱动。
将逻辑与引擎线程分离,游戏循环将不会影响我们看到的帧率,游戏帧率会更稳定的同时允许游戏循环以一个和引擎不一样的帧率去工作。
《无尽之路》的实现
玩法与逻辑实现
玩法与规划:
- 场景里提前摆好了浮空的小球
- 玩家靠近小球自由落体,落体后爆炸,一定范围内玩家会掉血
- 悬在空中的小球越少,重力越高
- 玩家没血了失败
- 玩家成功抵达中心的大球下方胜利
架构
容器与子系统:
- 游戏循环驱动各子系统
- 子系统是游戏设计模式的体现,提供了常见的游戏机制
通用组件:
- 在引擎支持下提供游戏逻辑无关的功能
脚本:
- 游戏玩法与逻辑实现
开发方式
支撑游戏的功能
UI
UGUI
- 前身是 NGUI
- Unity3D 底层提供基础支持 Canvas、CanvasRender
- 游戏的 UI 系统本质上就是用 quad + 纹理来拼接 UI 表现
- 输入系统,事件分发与冒泡
Tween
- 位置动画
- 颜色动画
- alpha 动画
通用功能
ScreenInput.cs
- 遥感移动
- 键盘移动
- 相机 yaw 调整
- 相机高度调整
- 相机距离调整
ObjectDetector.cs
- 视野 KdTree 管理场景里的小球
- 定时查询玩家周围的小球并发送剧情信息
StoryObject.cs
- 打开 RigidBody 的 useGravity
- Unity3D 碰撞回调
- 头顶飘字
- 特效播放
- 音效播放
StoryCamera.cs
- 跟随目标
- Lookat 目标或指定位置
- 相机拉近、推远
- 相机绕目标旋转等