离散仿真引擎基础作业与练习(一)

离散仿真引擎基础作业与练习(一)

一、简答题

  • 解释 游戏对象(GameObjects) 和 资源(Assets)的区别与联系。
    答:
    区别:游戏对象指的是游戏中的对象比如一个npc,一幕场景。游戏对象本身什么都不做,但是它是是组件的容器,可以通过添加组件使游戏对象具有某些特性从而成为游戏中的对象。
    资源相当于一种模板,可以在asset store中下载(或者自己另外添加)来使用,包括图片、音频、视频、代码文件等。
    联系:资源可以作为模板创建对象;游戏对象可以作为资源保存。

  • 下载几个游戏案例,分别总结资源、对象组织的结构(指资源的目录组织结构与游戏对象树的层次结构)
    答:
    asset以文件夹(目录)的形式来组织,按照文件类型分类我们可以把他们放到不同的文件夹,在unity客户端的project选项卡中可以看到这种组织结构:
    这里写图片描述
    对象通过层次结构来组织,通过整体-部分的关系构成层次结构,在unity的hierarchy选项卡中可以看到这种组织结构:
    这里写图片描述

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

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

    答:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class MyMonoBehaviourTestScript : MonoBehaviour {
    
        void Start () {
            Debug.Log("test start");
        }
    
        void Update () {
            Debug.Log("test update");
        }
    
        private void Awake()
        {
            Debug.Log("test awake");
        }
        private void FixedUpdate()
        {
            Debug.Log("test fixedupdate");
        }
    
        private void LateUpdate()
        {
            Debug.Log("test lateupdate");
        }
    
        private void OnGUI()
        {
            Debug.Log("test ongui");
        }
    
        private void OnDisable()
        {
            Debug.Log("test ondisable");
        }
    
        private void OnEnable()
        {
            Debug.Log("test enable");
        }
    }

    程序启动:
    这里写图片描述
    程序运行的每一帧:
    这里写图片描述
    程序结束:
    这里写图片描述
    分析:
    启动时awake首先被调用,然后start在所有的update之前被调用,之后enable被调用保证object被渲染;
    运行时的每一帧,都会调用FixedUpdate,Update,LateUpdate,OnGUI,其中当MonoBehaviour启用时,其Update在每一帧被调用。当MonoBehaviour启用时,其 FixedUpdate在每一帧被调用。区别是:update跟当前平台的帧数有关,而FixedUpdate是真实时间,Update是在每次渲染新的一帧的时候才会调用,也就是说,这个函数的更新频率和设备的性能有关以及被渲染的物体(可以认为是三角形的数量)。这会导致同一个游戏在不同的机器上效果不一致(不同设定下也不同),有的快有的慢。因为Update的执行间隔不一样了。而FixedUpdate,是在固定的时间间隔执行,不受游戏帧率的影响。

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

    • 分别翻译官方对三个对象的描述(Description)
      答:
      GameObject 游戏物体,是Unity场景里面所有实体的基类;
      Transform指的是一个组件(component),用来控制物体的位置、旋转和缩放。每一个GameObject都可以添加Transform用来储存并它的位置、旋转和缩放。每一个Transform可以有一个父级,它的变换是相对与它的父级的。可以在Hierarchy面板查看层次关系:
      这里写图片描述
      Component 组件,一切附加到游戏对象的基类,变换(transform)、脚本、音频都可以算是组件,可以添加到游戏对象中;
    • 描述下图中 table 对象(实体)的属性、table 的 Transform的属性、 table 的部件
      这里写图片描述

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

      答:
      table对象的属性: static、layer、tag、prefab等;
      table的transform属性: position:(0,0,0),rotation(0,0,0),scale(1,1,1);
      table的组件: transform、mesh render、box colider、cube(mesh filter)等;

    • 用UML 图描述 三者的关系(请使用 UMLet 14.1.1 stand-alone版本出图)
      这里写图片描述
  • 整理相关学习资料,编写简单代码验证以下技术的实现:

    • 查找对象
      static GameObject Find (string name)
      name指的是是单个的对象的名字,也可以是hierarchy中的一个路径名,如果找到会返回该对象,如果找不到就返回;
      static GameObject FindWithTag (string tag)
      根据tag属性查找单个对象,如果有某个对象以的tag属性是符合的返回该对象,没有则返回null。
      static GameObject[] FindGameObjectsWithTag (string tag)
      根据tag属性查找对象集合,如果有某个/多个对象以的tag属性是符合的返回这些对象的集合,没有则返回null。
      static Object FindObjectOfType(Type type)
      根据type查找单个游戏对象,如果有某个对象是type类型的返回该对象(该对象是查找到的第一个类型为type的对象),没有则返回null。
      FindObjectsOfType方法:static Object FindObjectsOfType(Type type)
      根据type查找游戏对象集合,返回所有类型为type的游戏对象的集合,没有则返回null。
      简单代码验证:

      var cube1 = GameObject.Find("Cube/Cube1");
      if (null != cube1)
      {
          Debug.Log("find cube1 by path");
      }
      cube1 = GameObject.Find("Cube1");
      if (null != cube1)
      {
          Debug.Log("find cube1 by name");
      }
      cube1 = GameObject.FindWithTag("test");
      if (null != cube1)
      {
          Debug.Log("find cube1 by tag");
      }

      运行结果:
      这里写图片描述
      从图片中可以看出我们分别通过路径、tag属性、name属性进行了查找而且都成功查找

    • 添加子对象
      答:

      GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
      cube.name = "Cube5";
      cube.transform.position = new Vector3(-2, -2, -2);

      运行前:只有四个方块,目录下也只有四个
      这里写图片描述
      运行后:产生了第五个方块,目录新增Cube:
      这里写图片描述

    • 遍历对象树

      foreach (Transform child in transform)
      {
          Debug.Log("childname:"+child.name);
      }

      这一段代码打印所有的child的名字,运行结果如下:
      这里写图片描述

    • 清除所有子对象

      foreach (Transform child in transform)
      {
          GameObject.Destroy(child);
      }
      int count = 0;
      foreach (Transform child in transform)
      {
          count++;
      }
      
      Debug.Log(count);

      这一段代码清除子对象之后打印结果,结果表明所有子对象都被删除了:
      这里写图片描述

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

    • 预设(Prefabs)有什么好处?
      利用预设可以快速生成相同对象,而且修改预设就可以完成对生成对象的修改,就不需要在后期优化时在多个地方修改了,这样可以大大节省开发时间;
    • 预设与对象克隆 (clone or copy or Instantiateof Unity Object) 关系?
      预设与克隆都能创建出相同的对象。预设创建出的对象与源预设还有联系,源预设修改了由预设创建的对象也会被修改(也就是说他们之间有某种东西链接着)。克隆出的对象与源对象不再有联系,克隆就仅仅是把原本对象复制了一份而已。
    • 制作 table 预制,写一段代码将 table 预制资源实例化成游戏对象

          GameObject prefabTable = (GameObject)Instantiate(Resources.Load("table"));
          prefabTable.transform.position = new Vector3(3, 3, 3);

      运行结果:在指定位置创建了新的“table”
      这里写图片描述
      注意这里一定要把预制的东西放到一个叫做resources的文件夹下才能被resource.load读到

  • 尝试解释组合模式(Composite Pattern / 一种设计模式)。使用 BroadcastMessage() 方法向子对象发送消息
    查阅相关资料得知:组合模式—-将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。通俗点讲就是在组合模式下,处理单个对象和组合对象的方法、思想都是一样的。这样使我们可以使用处理简单事件的方法和思想来解决复杂的事情,从而使事情得到简化。比如我们使用计算机但是并不需要自己手动编辑每一个指令,我们只需要从键盘鼠标输入,然后由下面一层完成它的操作(下面一层又把它的工作分给再下面一层,不断如此使得每一层需要完成的事情都比较简单)。
    向子对象发送消息:
    创建parent.cs和child.cs,绑定到同一个object
    其中parent.cs:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class parent : MonoBehaviour {
        string message = "I'm your father";
        // Use this for initialization
        void Start () {
            this.BroadcastMessage("MyChild", message);
        }
    
        // Update is called once per frame
        void Update () {
    
        }
    }
    

    其中child.cs:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class child : MonoBehaviour {
    
        // Use this for initialization
        void Start () {
    
        }
    
        void MyChild(string message)
        {
            Debug.Log("My father said to me:\""+message+"\"");
        }
    
        // Update is called once per frame
        void Update () {
    
        }
    }
    

    最后运行结果:即parent讲message传给了子类函数Mychild,并且由子类调用了这个函数
    这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值