3D游戏02-离散仿真引擎

简答题

1. 解释游戏对象(GameObjects) 和资源(Assets)的区别与联系。

游戏对象(GameObjects) 指的是游戏中一个可被选中的对象,比如一个方块,一幅平面、一位角色形象等。对象可以被赋予一些属性,进而完成某些动作。
资源(Assets) 则是一个游戏项目中的素材,比如音频、视频、脚本文件、模型等。
它们之间的联系是,资源可以被实例化成游戏对象,游戏对象也可以被保存为资源。一个资源可以被多个游戏对象使用,也可能不被任何对象使用。

2. 下载几个游戏案例,分别总结资源、对象组织的结构(指资源的目录组织结构与游戏对象树的层次结构)

资源目录下,根据资源的性质(Plugins,Code,Scene…),分成几个子目录,分别存放不同类型的资源。
子目录下再进行分类(比如Resource目录下的Effect,Image,Runtime…)方便对资源进行管理。
在这里插入图片描述
游戏对象的结构如下,可以看到这个游戏中有camera,Root,EventSystem,BDFrame等对象
在这里插入图片描述
3. 编写一个代码,使用 debug 语句来验证 MonoBehaviour 基本行为或事件触发的条件

  • 基本行为包括 Awake() Start() Update() FixedUpdate() LateUpdate()
  • 常用事件包括 OnGUI() OnDisable() OnEnable()
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("Start");
    }

    // Update is called once per frame
    void Update()
    {
        Debug.Log("Update");
    }
    void Awake()
    {
        Debug.Log("Awake");
    }
    void FixedUpdate()
    {
        Debug.Log("FixedUpdate");
    }
    void LateUpdate()
    {
        Debug.Log("LateUpdate");
    }
    void OnGUI()
    {
        Debug.Log("onGUI");
    }
    void OnDisable()
    {
        Debug.Log("onDisable");
    }
    void OnEnable()
    {
        Debug.Log("OnEnable");
    }
}

运行结果:
在这里插入图片描述

4. 查找脚本手册,了解 GameObject,Transform,Component 对象

  • 分别翻译官方对三个对象的描述(Description)

游戏对象 是代表人物、道具和场景的基本对象。它们本身并没有完成多少工作,但是它们充当组件的容器,组件实现真正的功能。
Transform 组件决定场景中每个对象的位置、旋转和比例。每个游戏对象都有一个Transform。
Component 是游戏中对象和行为的螺母和螺栓。它们是每个游戏对象的功能部件。

  • 描述下图中 table 对象(实体)的属性、table 的 Transform 的属性、 table 的部件

    • 本题目要求是把可视化图形编程界面与 Unity API 对应起来,当你在 Inspector 面板上每一个内容,应该知道对应 API。
    • 例如:table 的对象是 GameObject,第一个选择框是 activeSelf 属性。在这里插入图片描述

    table的属性:activeInHierarchy(对象在当前场景中是否为active),ObjectName,activeSelf(对象在本地是否为active),Tag,Layer,prefabs(预设)
    transform的属性:Position,Rotation,Scale
    table的部件:Mesh Filter,Box Collider,Mesh Renderer

  • 用 UML 图描述 三者的关系(请使用 UMLet 14.1.1 stand-alone版本出图)

在这里插入图片描述
5. 整理相关学习资料,编写简单代码验证以下技术的实现:

  • 查找对象

      ```
      	//按照名字对象名查找
      	public static GameObject Find(string name)
      	//按照标签查找单个对象
      	public static GameObject FindWithTag(string tag)
      	//按照标签查找多个对象
      	public static GameObject[] FindGameObjectsWithTag(string tag)		
      ```
    
    • 添加子对象

      public static GameObect CreatePrimitive(PrimitiveTypetype)
      
    • 遍历对象树

      	foreach (Transform child in transform) {  
      	  Debug.Log(child.gameObject.name);  	} 
      
    • 清除所有子对象

      	foreach (Transform child in transform) {
       		Destroy(child.gameObject);		}
      

8. 资源预设(Prefabs)与 对象克隆 (clone)

  • 预设(Prefabs)有什么好处?
  1. 预设相当于模板,方便我们创建具有相同属性和行为的对象。
  2. 预设方便管理对象。当同一类型的对象需要改变某些属性时,我们只需要修改它们的预设即可。
  • 预设与对象克隆 (clone or copy or Instantiate of Unity Object) 关系?
  1. 克隆必需是在已经存在一个对象的情况下,克隆出另外一个对象;而预设可以创造一个原先不存在的对象。
  2. A由B克隆得到,则B发生改变不会影响A;而预设发生改变时会影响所有创建的对象。
  • 制作 table 预制,写一段代码将 table 预制资源实例化成游戏对象

    public GameObject table;
     void Start () {
     	   Debug.Log("Init Start");
     	   GameObject newTable = (GameObject)Instantiate(table.gameObject);
    }
    

    编程实践

  • 游戏内容: 井字棋 或 贷款计算器 或 简单计算器 等等

  • 技术限制: 仅允许使用 IMGUI 构建 UI

  • 作业目的:

    • 解 OnGUI() 事件,提升 debug 能力
    • 提升阅读 API 文档能力

作业链接:https://github.com/akanine/Unity3d_TicTacToe/tree/master
井字棋是一种在3*3棋盘上完成的连珠游戏,类似于五子棋
实现效果如下:

在这里插入图片描述

思考题

  • 微软 XNA 引擎的 Game 对象屏蔽了游戏循环的细节,并使用一组虚方法让继承者完成它们,我们称这种设计为“模板方法模式”。
  • 为什么是“模板方法”模式而不是“策略模式”呢

模板方法模式是类的行为模式。准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后生命一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意。

策略模式定义一组算法,这组算法实现了相同的接口或者继承相同的抽象类。将每一个算法封装起来,从而使它们可以相互切换。
策略模式是对象的行为模式。

微软XNA引擎的Game对象实际上是一组抽象类,因为它“屏蔽了游戏循环的细节,而使用虚方法让继承者完成细节”。符合模板方法模式的意图,增强了game对象的拓展性,且使其易于维护;而策略模式的关键意图在于封装相似的算法使它们可以互相替换,但这样会导致策略类繁多和暴露,不符合game对象的设计要求。

  • 将游戏对象组成树型结构,每个节点都是游戏对象(或数)。
    • 尝试解释组合模式(Composite Pattern / 一种设计模式)。

组合模式用树形结构来组合对象,表示部分以及整体的层次。把一组相似的对象当成一个单一对象,使用户对单个对象和组合对象的使用具有一致性。使复杂元素的内部解耦、节点可自由增加、调用简单。

  • 使用 BroadcastMessage() 方法,向子对象发送消息。你能写出 BroadcastMessage() 的伪代码吗?

      public class NewBehaviourScript : MonoBehaviour {
      	  void message() {
          Debug.Log("HelloWorld!");
        }
       void Start () {
      	  this.BroadcastMessage("parent");
        }
    }
    
      public class NewBehaviourScript1 : MonoBehaviour {
       void message() {
      		Debug.Log("HelloWorld!");
        }
      }
    
  • 一个游戏对象用许多部件描述不同方面的特征。我们设计坦克(Tank)游戏对象不是继承于GameObject对象,而是 GameObject 添加一组行为部件(Component)。

    • 这是什么设计模式?
      装饰器模式
    • 为什么不用继承设计特殊的游戏对象?
    1. 采用装饰器模式,装饰类和被装饰类可以独立发展,不会相互耦合
    2. 继承会增加过多的子类
    3. 继承不能方便地动态添加/撤销功能
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值