离散仿真引擎基础
简答题
一、解释 游戏对象(GameObjects) 和 资源(Assets)的区别与联系。
游戏对象(GameObjects),游戏程序空间中的事物,可能是 Empty(空,最有用的事物)、2D、3D、光线、摄像机等。
游戏资源(Assets),构造游戏对象、装饰游戏对象、配置游戏的物体和数据。即序列化的或存储格式的游戏对象或数据。不仅仅包括GameObject,还有一些C#文件以及音频文件等来对游戏对象进行修饰。
联系:资源可以作为模板,实例化成具体的游戏对象,也可以作为游戏对象中的某种属性,同时也可以被多个游戏对象同时使用。
二、下载几个游戏案例,分别总结资源、对象组织的结构(指资源的目录组织结构与游戏对象树的层次结构)
目录组织包括:
Material: 包括制作游戏的材质
Prefab: 包括GameObjects的各种预制
Scripts: 包括C#文件,用于指定物体的行为、变化
Animation: 用于设置物体起始,移动,终止时的动作效果
resources:动态加载的资源文件
该游戏资源的内容分为预制、脚本等等,按照文件的类型的不同,添加到不同的文件夹当中,便于后面的资源整理和利用。
游戏对象分为游戏的控制,环境的设置,玩家以及目标,符合游戏的各个必要的环节。
三、编写一个代码,使用 debug 语句来验证 MonoBehaviour 基本行为或事件触发的条件
基本行为包括 Awake() Start() Update() FixedUpdate() LateUpdate(); 常用事件包括 OnGUI() OnDisable() OnEnable()using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript1 : MonoBehaviour {
void Awake()
{
Debug.Log("Awake!");
}
void Start()
{
Debug.Log("Start!");
}
void Update()
{
Debug.Log("Update!");
}
void FixedUpdate()
{
Debug.Log("FixedUpdate!");
}
void LateUpdate()
{
Debug.Log("LateUpdate!");
}
void Reset()
{
Debug.Log("Reset!");
}
void OnGUI()
{
Debug.Log("onGUI!");
}
void OnDisable()
{
Debug.Log("onDisable!");
}
void OnDestroy()
{
Debug.Log("onDestroy!");
}
}
分析
awake:当一个脚本实例被载入时被调用
start:在所有update函数之前被调用一次
update:当行为启用时,其update在每一帧被调用
fixedupdate:当行为启用时,其fixedupdate在每一时间片被调用
OnGUI:渲染和处理GUI事件时调用
OnEnable:当对象变为可用或激活状态时被调用
OnDisable:当对象变为不可用或非激活状态时被调用
运行结果:
四、查找脚本手册,了解 GameObject,Transform,Component 对象
分别翻译官方对三个对象的描述(Description)
GameObject: 游戏中的每个对象都是一个游戏对象(GameObject)。然而,游戏对象(GameObjects)本身不做任何事情。它们需要特殊属性(special properties)才能成为一个角色、一种环境或者一种特殊效果。
Transform:变换(Transforms)是每个游戏对象(GameObject)的关键组件(Component)。它们决定游戏对象 (GameObject)的位置、旋转方式及缩放。
Reset:在游戏中,组件(Components)就是对象和行为的螺栓与螺母,它们是每个游戏对象 (GameObject)的功能零件。
描述下图中 table 对象(实体)的属性、table 的 Transform 的属性、 table 的部件
本题目要求是把可视化图形编程界面与 Unity API 对应起来,当你在 Inspector 面板上每一个内容,应该知道对应 API。
例如:table 的对象是 GameObject,第一个选择框是 activeSelf 属性。
描述属性
第一个选择框是activeSelf:可以定义对象的名称,动静态等属性
第二个选择框是Transform:可以定义对象的位置、面向方向、大小
第三个选择框是Box Collider:可以调整坐标系的位置、大小
第四个选择框是Component:可以给对象增加行为
用 UML 图描述 三者的关系(请使用 UMLet 14.1.1 stand-alone版本出图)
五、资源预设(Prefabs)与 对象克隆 (clone)
预设(Prefabs)有什么好处?
- 可以回收再利用对象,不需每次都从基础游戏对象构建游戏。
- 相同的游戏对象可以用同一个预设来创建。
- 对预设进行修改后,所有的游戏对象都会发生改变(批量处理)。
预设与对象克隆 (clone or copy or Instantiate of Unity Object) 关系?
- 对象克隆不受克隆本体的影响,因此A对象克隆的对象B不会因为A的改变而相应改变。
制作 table 预制,写一段代码将 table 预制资源实例化成游戏对象
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class example : MonoBehaviour {
public GameObject prefab;
void Start() {
GameObject instance = (GameObject)Instantiate(prefab, transform.position, transform.rotation);
}
}
编程实践
首先是实现井字棋,确定输赢情况,当X或者O横向或者竖向或者斜向连成线,则胜利。然后通过OnGUI()函数构造画面。
井字棋运行结果:
具体代码参见git
OnGUI()
OnGUI是Unity中通过代码驱动的GUI系统
主要用来创建调试工具、创建自定义属性面板、创建新的Editor窗口和工具达到扩展编辑器效果。
在本次小游戏中使用了Label和Button,具体用法参考了https://www.cnblogs.com/sanyejun/p/8483759.html
思考题
-
微软 XNA 引擎的 Game 对象屏蔽了游戏循环的细节,并使用一组虚方法让继承者完成它们,我们称这种设计为“模板方法模式”。
模板方法定义了一个过程或算法中的核心步骤,而对于子步骤或是子方法则是使用继承或接口在子类中实现,从而使得可以通过不改变整体而对一些子步骤进行重构;策略模式则是指对象具备某个行为,但是在不同的场景中,该行为有不同的实现算法。对于微软的XNA引擎,其屏蔽了游戏循环的细节,并使用一组虚方法由继承者完成,目的就是使得可以在不改变代码基本结构的情况下将一些具体模块交由继承者具体实现,这明显更符合“模板方法”,而非“策略模式”。 -
将游戏对象组成树型结构,每个节点都是游戏对象(或数)。
- 尝试解释组合模式(Composite Pattern / 一种设计模式)。
将对象组合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
- 使用 BroadcastMessage() 方法,向子对象发送消息。你能写出 BroadcastMessage() 的伪代码吗?
父对象
public class father1 : MonoBehaviour {
void Update () {
var object = GameObject.Find ("object");
object.BroadcastMessage ("tested", 5.0);
}
}
子对象
public class child1 : MonoBehaviour {
void test(int i){
Debug.Log ("tested for " + i);
}
}
- 一个游戏对象用许多部件描述不同方面的特征。我们设计坦克(Tank)游戏对象不是继承于GameObject对象,而是 GameObject 添加一组行为部件(Component)。
- 这是什么设计模式?
Decorator模式。
-
为什么不用继承设计特殊的游戏对象?
Decorator模式允许向一个现有的对象添加新的功能,同时又不改变其结构。与Decorator模式相比,使用多重继承容易使代码变得脆弱且不易理解,并且使得耦合变得很高。因此,我们应该优先使用模式,而非继承,从而能够更加灵活地给对象添加额外的职责,并更加清晰的划分各个代码模块。如果使用继承的话,在编译的时候就得分配职责,缺乏灵活性,而且会产生子类,导致混杂。