游戏离散仿真基础
3D游戏与编程(离散仿真基础)
游戏引擎
游戏引擎是一个专门设计给人们用来制作游戏的软件的开发环境,是一组游戏运行部件以及软件工具的集合。
游戏引擎的架构:

分为两个层次:
-
- 游戏内容层 :一组工具管理游戏需要的数据
-
- 游戏引擎层 : 一组游戏运行部件,支撑游戏的运行和人机交互
现代游戏都是数据驱动的架构,即 游戏代码工作量一般不太大,游戏的行为、规则主要由数据驱动。
模板方法模式
模板方法(Template Method):定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的
情况下重定义该算法的某些特定步骤。
游戏的循环实现非常复杂,而模板方法使得程序员在一般情况下仅仅需要关注游戏的对象Update即可。
游戏循环与多线程
游戏循环能且只能单线程完成,单CPU能力与GPU能力对游戏软件最重要。因为:
1. 窗口设备相关句柄不是多线程安全的。
2. 数据依赖关系的约束使得游戏资源创建、修改、渲染、卸载必须有序执行,例如Draw阶段被Draw的对象的属性
不能改变,即与Update阶段不能同时进行。
离散仿真与离散事件仿真
系统状态变化可能是离散的、也可能是连续的,
但游戏程序只能在离散的点上计算游戏对象
离散仿真
为了研究系统动态,事件被分成若干小的时间片,系统状态被这段时间内发生的系列活动而改变。
- 时间轴
为了解释或预测系统变化的规律,必须选择合适的时间轴并在上选择一组点观察或记录系统状态。
1. 游戏时间-虚拟世界的时间系统,如:石器时代、铁器时代、火器时代、太空时代。
2. 渲染时间-游戏引擎的时间系统,通常用Tick表示从游戏开始游戏循环的次数。
- FPS(Frames PerSecond) 视频游戏最重要的概念
它是每秒钟游戏循环执行DrawGameObjects的次数。如果低于30次/s,玩家会感觉明显的动作不流畅。
- 在特定性能机器上,它是评价游戏优化的指标
- 在不同机器上,它是机器游戏性能的综合指标
- 系统状态
某一时刻,系统中所有对象、及其属性与关联
- 问题:
-
跳帧。 UpdateGameObjects或DrawGameObjects花费的时间过多,就会产生帧间隔超出给定时间的问题。
-
穿越。 可能失去两次计算之间的存在的重要的状态。
离散事件仿真(Discrete Event Simulation,缩写为DES)
为了研究系统动态,系统中对象处理在内部(如对象状态改变产生时间)、外部事件、并在事件
处理过程中进一步引发系统状态改变产生系统事件。与离散仿真不同,我们是在特定事件中观察并改变系统状态。
作业内容
1. 简答题
- 解释游戏对象(GameObjects)和资源(Assets)的区别与联系。
基本概念:
-
游戏对象(GameObjects),游戏程序空间中的事物,可能是Empty(空,最有用的事物)、2D、3D、光线、摄像机等
- GameObject: Unity场景中所有实体的基类
- Component:能附加到游戏对象的部件的基类
- Componet的各种子类。包括空间与变换部件Transform、各种渲染部件Reander,脚本部件MonoBehaviour的子类等等。

游戏对象一般不能被继承且组合优于继承
-
游戏资源(Assets),构造游戏对象、装饰游戏对象、配置游戏的物体和数据。即序列化的或存储格式的游戏对象或数据
两者之间的联系:
对象一般是一些资源的集合体,是资源整合的具体表示。资源可以被多个对象使用。资源可以作为模板,实例化游戏对象。
例如游戏对象可以为玩家、敌人和环境等等,而资源可组成游戏中所有的对象,一般包括声音,脚本和材质等。
- 下载几个游戏案列,分别总结资源、对象组织的结构(指资源的目录组织结构与游戏对象书的层次结构)
资源的目录组织结构主要文件、材质、模型、预制、场景、脚本、标准资源(图片、游戏需要用到的音乐等等)这几个部分。游戏对象树就如同Windows的文件资源管理一样,树目录结构:一个游戏对象(文件夹)包含多个子对象(子文件夹),子对象(子文件夹)又可以继续包含多个子对象(子文件夹)。


- 编写一个代码,使用debug语句来验证MonoBehaviour基本行为或事件触发的条件
- 基本行为包括Awake() Start() Update() FixedUpdate() LateUpdate()
- 常用事件包括OnGUI() OnDisable() OnEnable()

Awake():当前控制的脚本实例被装载的时候调用。在测试中只调用了一次。一般用于初始化整个实例。
Start():当前的控制脚本第一次执行Update之前调用。
Update():每帧都执行一次,是最常用的事件函数。
FixedUpdat():每固定帧绘制时执行一次,和Update不同的时FixedUpdate是渲染帧执行,如果你的渲染效率低下的时候FixedUpdate的调用次数就会减少。
LateUpdate():在每帧执行完毕后调用,并且在所有Update结束后调用。
OnEnale():当对象变为可用或激活状态时此函数被调用。
OnDisable():当对象变为不可用或非激活状态时此函数被调用。当物体被销毁时它被调用,并且可用于清理任意代码。
OnGUI():绘制GUI时触发,一般在这个函数里绘制GUI菜单。
- 查找脚本手册,了解GameObject,Transform,Component对象
-
分别翻译官方对三个对象的描述(Description)
GameObject

- 翻译:Unity场景中所有实体的基类
Transform

- 翻译:一个对象的位置,是否旋转和它的规模
Component

- 翻译:一切附加到游戏物体的基类
- 描述下图中table对象(实体)的属性、table的Transform属性、table部件

- 第一个选择框是activeSelf:可以定义对象的名称,动静态等属性
- 第二个选择框是Transform:可以定义对象的位置、面向方向、大小
- 第三个选择框是Box Collider:可以调整坐标系的位置、大小
- 第四个选择框是Component:可以给对象增加行动
- 用UML图描述三者的关系(请使用UMLet 14.1.1 stand-alone版本出图)

- 资源预设(Prefabs)与对象克隆(clone)
- 预设(Prefabs)有什么好处?
预设可以提前将游戏设计中所需要的游戏对象进行设计打包,成为一个模板。在设计过程中,随时可以直接从Assets当中加载,成为一个游戏对象。
预设的存在,方便了面向对象思想的应用,方便我们在设计游戏中更加便捷。预设可以放入到多个场景中,而且在每个场景中能够使用多次。
所有预设实例都会链接到原始的预设,实质上是原始预设的克隆。
- 预设与对象克隆(clone or copy or Instantiate of Unity Object)关系?
在Unity3D中。主要有两种方法快速复制出游戏对象
- 克隆游戏对象
- 创建预制
两者的区别:
- 克隆游戏对象需要当前场景中存在被克隆的对象,而创建预制秩序事先创建预制即可,即允许场景中一开始不存在该游戏对象。
- 克隆出来的游戏对象并不会随着被克隆体的变化而变化。但是由于所有预设实例都会连接到原始的预设,使用预设创建出啦的对象会随着预设的改变而发生改变。
- 制作table预制,写一段代码将table预制资源实例化成游戏对象

脚本挂载到空对象上后,产生了table(clone)

2.编程实践,小游戏
- 游戏内容: 井字棋 或 贷款计算器 或 简单计算器 等等
- 技术限制: 仅允许使用 IMGUI 构建 UI
- 作业目的:
- 了解 OnGUI() 事件,提升 debug 能力
- 提升阅读 API 文档能力
井字棋
- 脚本的结构:

- 游戏效果:

浙公网安备 33010602011771号