3D游戏编程与设计第一次作业

作业内容

简答题

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

游戏对象:在游戏场景中出现的物体都是游戏对象。
资源:游戏项目中的素材,可以包括模型、图形、音频、脚本等。
联系:游戏对象可以保存为资源,资源可以实例化为游戏对象。

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

只能找到资源的结构,游戏对象树网络上没找到。

总的来说,资源的目录组织结构主要包含文件、材质、模型、预制件、场景、脚本、标准资源这几个部分。资源里面又包含了图片,游戏需要用到的音乐等等。
在这里插入图片描述
游戏对象树就如同Windows的文件资源管理器一样,树目录结构:一个游戏对象(文件夹)包含多个子对象(子文件夹),子对象(子文件夹)又可以继续包含多个子对象(子文件夹)
在这里插入图片描述
在这里插入图片描述

3.编写一个代码,使用 debug 语句来验证MonoBehaviour 基本行为或事件触发的条件

  • 基本行为包括 Awake() Start() Update() FixedUpdate() LateUpdate()**
  • 常用事件包括 OnGUI() OnDisable() OnEnable()**

代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

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

    void Awake()
    {
        Debug.Log("Awake");
    }

    // Update is called once per frame
    void Update()
    {
        Debug.Log("Update");
    }

    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");
    }
}

运行结果图如下:
在这里插入图片描述
在这里插入图片描述
start函数:在所有update函数调用之前调用一次;

awake函数:主要用于一个脚本被实例装载时调用;

Update函数:当对象可见时,每帧都执行一次(每一帧的时间不固定);

FixedUpdate函数:当对象可见时,每固定时间片执行一次(每帧与每帧之间相差的时间是固定的);

LateUpdate函数:在所有Update函数调用后被调用。可用于调整脚本执行顺序。例如:当物体在Update里移动时,跟随物体的相机可以在LateUpdate里实现;

OnGUI函数:绘制GUI时候触发。一般在这个函数里绘制GUI菜单;

OnDisable函数: 当对象变为不可用或非激活状态时此函数被调用。

OnEnable函数:当对象变为可用或激活状态时此函数被调用。

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

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

    GameObject:是Unity场景里面所有实体的基类.
    Transform:物体的位置、旋转和缩放。
    Component:一切附加到游戏物体的基类。

  • 描述下图中 table 对象(实体)的属性、table 的 Transform 的属性、 table 的部件
    • 本题目要求是把可视化图形编程界面与 Unity API 对应起来,当你在 Inspector 面板上每一个内容,应该知道对应 API。
    • 例如:table 的对象是 GameObject,第一个选择框是 activeSelf 属性。

在这里插入图片描述
第一个选择框是activeSelf:可以定义对象的名称,动静态等属性,比如上图,对象名称是table
第二个选择框是Transform:可以定义对象的位置、面向方向、大小
第三个选择框是Box Collider:可以调整坐标系的位置、大小
第四个选择框是Add Component:可以给对象增加行为,比如给对象增加C#script

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

在这里插入图片描述

  • 5.整理相关学习资料,编写简单代码验证以下技术的实现:

    • 查找对象
     using System.Collections;
     using System.Collections.Generic;
     using UnityEngine;
     
     public class Find : MonoBehaviour {
     
     	// Use this for initialization
     	void Start () {
     		GameObject find1 = GameObject.Find ("chair1");
     		if (find1 == null) {
     			Debug.Log ("Can't find chair1");
     		} 
     		else {
     			Debug.Log ("Find chair1");
     		}
     		GameObject find2 = GameObject.Find ("chair5");
     		if (find2 == null) {
     			Debug.Log ("Can't find chair5");
     		} 
     		else {
     			Debug.Log ("Find chair5");
     		}
     	}
     	
     	// Update is called once per frame
     	void Update () {
     		
     	}
    

    运行结果如下
    在这里插入图片描述
    总的来说,查找对象有两种方法,根据名字、标签

    //通过名字查找
     public static GameObject Find(string name); 
     //通过标签查找单个对象
     public static GameObject FindWithTag(string tag);
     //通过标签查找多个对象
     public static GameObject[] FindGameObjectsWithTag(string tag);
    
    • 添加子对象
      using System.Collections;
      using System.Collections.Generic;
      using UnityEngine;
      
      public class Create : MonoBehaviour {
      	public GameObject table;
      	// Use this for initialization
      	void Start () {
      		GameObject createCube = GameObject.CreatePrimitive(PrimitiveType.Cube);
      		createCube.name = "cube2";
      		createCube.transform.position = new Vector3(0, Random.Range(0, 5), 0);
      		createCube.transform.parent = this.transform;
      		GameObject table2 = GameObject.Instantiate (table);
      		table2.name = "table2";
      		table2.transform.position = new Vector3(3, Random.Range(0, 5), 0);
      		table2.transform.parent = this.transform;
      	}
      	
      	// Update is called once per frame
      	void Update () {
      		
      	}
      }
    

    这里创建了两个对象,一个是Cube,一个是预制得到的table,首先将代码拖到CreateObj这个空对象里
    在这里插入图片描述
    会发现component一项的Table是空的,将Assets中的table拖入即可,然后点击运行,就会发现CreateObj对象里多出了两个子对象,一个叫cube2,一个是table2
    在这里插入图片描述

    • 遍历对象树
      using System.Collections;
      using System.Collections.Generic;
      using UnityEngine;
      
      public class Traverse : MonoBehaviour {
      
      	// Use this for initialization
      	void Start () {
      		foreach(Transform child in transform){
      			Debug.Log(child.name);
      		}
      	}
      	
      	// Update is called once per frame
      	void Update () {
      		
      	}
      }
    

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

    • 清除所有子对象
      using System.Collections;
      using System.Collections.Generic;
      using UnityEngine;
      
      public class Delete : MonoBehaviour {
      
      	// Use this for initialization
      	void Start () {
      		foreach (Transform child in transform) {  
      			Destroy(child.gameObject);  
      		} 
      	}
      	
      	// Update is called once per frame
      	void Update () {
      		
      	}
      }
    

    运行前:
    在这里插入图片描述
    运行后:
    在这里插入图片描述

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

  • 预设(Prefabs)有什么好处?
    预设可以快速实例化大量的相同的游戏对象,先代码量少,而且想要修改通过预设实例化出来的游戏对象,无需一一修改,只需要修改预设,就可以全部一同修改了。
  • 预设与对象克隆 (clone or copy or Instantiate of Unity Object) 关系
    预设实例化的游戏对象就好像只是引用了预设而已,共享预设的一切属性,如果预设被修改了,所有通过预设实例化的游戏对象都会被改变;克隆是复制一个一模一样的游戏对象,它们之间独立,互不干扰,修改任一一个游戏对象,也不会改变其他的克隆游戏对象。
  • 制作 table 预制,写一段代码将 table 预制资源实例化成游戏对象
    首先在一个场景里面画好一个table
    在这里插入图片描述
    然后将左边框里的游戏对象table拖动到Assets中,即可制得table预制
    在这里插入图片描述

编程实践,小游戏

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

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

  • 作业目的:

    1.了解 OnGUI() 事件,提升 debug 能力

    2.提升阅读 API 文档能力

    项目传送门

思考题

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

    • 为什么是“模板方法”模式而不是“策略模式”呢?

    模板方法模式:定义一个操作中算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。是一种行为模式。
    策略模式:定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化。是一种对象行为模式。

    模板方法更加强调:
    1)定义一个算法流程,这个流程上的多个点是可以变化的(具体实现在子类中完成),流程上的多个点一定是会被执行的,并且一定是按照特定流程被执行的。
    2)算法流程只有唯一的入口,对于点的访问是受限的;
    而策略模式更注重于: 一个“策略”是一个完整的算法,算法是可以被整体替换的。而模板方法只能被替换其中的特定点,算法流程是固定不可变的。

  • 将游戏对象组成树型结构,每个节点都是游戏对象(或数)。

    • 尝试解释组合模式(Composite Pattern / 一种设计模式)。

    组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。

    • 使用 BroadcastMessage() 方法,向子对象发送消息。你能写出 BroadcastMessage() 的伪代码吗?
      父对象代码
      using System.Collections;
      using System.Collections.Generic;
      using UnityEngine;
         
      public class Father : MonoBehaviour {
         
         // Use this for initialization
         void Start () {
         	this.BroadcastMessage("test");
         }
         	
         // Update is called once per frame
         void Update () {
         		
         }
      }
      
      子对象代码
      using System.Collections;
      using System.Collections.Generic;
      using UnityEngine;
      
      public class Son : MonoBehaviour {
      
         // Use this for initialization
         void Start () {
         	
         }
         	
         // Update is called once per frame
         void Update () {
         	
         }
      
         void test(){
         	Debug.Log ("Hello, father");
         }
      }
      
      将Father的拖到table中,Son拖到chair1中,点击运行观看控制台输出
      在这里插入图片描述
      在这里插入图片描述
  • 一个游戏对象用许多部件描述不同方面的特征。我们设计坦克(Tank)游戏对象不是继承于GameObject对象,而是 GameObject 添加一组行为部件(Component)。

    • 这是什么设计模式?

      装饰模式

    • 为什么不用继承设计特殊的游戏对象?

      装饰模式:动态给一个对象增加一些额外的职责。就增加对象功能来说,装饰模式比生成子类实现更为灵活。是一种对象结构型模式。

      装饰模式优点:

      1. 提供比继承更多的灵活性
      2. 可以动态地扩展一个对象的功能
      3. 具体构件类和具体装饰类可以独立地变化

      如果使用继承的话,在编译的时候就得分配职责,缺乏灵活性,而且会产生子类,导致混杂。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值