3D游戏编程 离散仿真引擎基础-作业

姓名:陈钦德 学号: 17343010 专业:软件工程

1、简答题【建议做】

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

我们查看官方文档对GameObjects的解释:

GameObjects are the fundamental objects in Unity that represent characters, props and scenery. They do not accomplish much in themselves but they act as containers for Components, which implement the real functionality.

官方文档的意思是GameObject是Unity的基础物件,本身不做事情,但是可以作为具体组成的容器。

官方文档对Assets的解释:

An asset is representation of any item that can be used in your game or project. An asset may come from a file created outside of Unity, such as a 3D model, an audio file, an image, or any of the other types of file that Unity supports. There are also some asset types that can be created within Unity, such as an Animator Controller, an Audio Mixer or a Render Texture.

资源指的是任何一切可以在项目或者游戏中使用的东西的展现。

它们的区别和联系是,一般GameObject是Assets的集合体,也就是说游戏对象是由资源组成的,同时游戏对象可以使用资源保存起来,同一份资源可以创建多个游戏对象,资源同时也可以是游戏对象的属性等。

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

一般来说分为如下几个:

  • Assets:主文件夹,包含所有工程需要用到的资源
  • Editor:所有在Editor和它的子文件夹的脚本,都不会作为运行期脚本被编译,而是作为动态添加Unity编译器功能的脚本来编译,在该文件夹和其子文件夹的脚本不能被添加到GameObject上
  • Materials:材料
  • Models:模型
  • Prefabs:预设
  • Scenes:场景
  • Textures:纹理
  • Scripts:C#脚本

里面还有更加细节的东西,但是都和项目本身的具体安排有关。

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

首先我们知道:

  • 基本行为包括 Awake() Start() Update() FixedUpdate() LateUpdate()

  • 常用事件包括 OnGUI() OnDisable() OnEnable()

      using System.Collections;
      using System.Collections.Generic;
      using UnityEngine;	 
      public class test : MonoBehaviour {
          private void Awake()
          {
              Debug.Log("Awake!");
          }
       
          void Start () {
              Debug.Log("Start!");
      	}
    
      	void Update () {
              Debug.Log("Update!");
      	}
       
          private void FixedUpdate()
          {
              Debug.Log("Fixedupdate!");
          }
       
          private void OnGUI()
          {
              Debug.Log("OnGUI!");
          }
       
          private void OnDisable()
          {
              Debug.Log("OnDisable!");
          }
       
          private void OnEnable()
          {
              Debug.Log("OnEnable!");
          }
      }
    

最后的结果为:
3D游戏编程 离散仿真引擎基础-作业_第1张图片

我们可以看得到Awake、OnEnable、Start、OnDisable都调用了一次。

  • awake:当一个脚本实例被载入时被调用,在整个脚本的生命周期之中只被调用一次。
  • start:在所有update函数之前被调用一次,在awake之后调用,同时start是在脚本被启动的时候调用。
  • update:当行为启用时,其update在每一帧被调用
  • fixedupdate:当行为启用时,其fixedupdate在每一时间片被调用
  • OnGUI:渲染和处理GUI事件时调用,如果MonoBehaviour的enabled属性设为false,OnGUI()将不会被调用。
  • OnEnable:当对象变为可用或激活状态时被调用
  • OnDisable:当对象变为不可用或非激活状态时被调用

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

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

GameObject :GameObjects are the fundamental objects in Unity that represent characters, props and scenery. They do not accomplish much in themselves but they act as containers for Components, which implement the real functionality.

翻译:游戏对象是Unity中表示角色、道具和场景的基本对象。它们本身不能够完成许多功能,但那时它们可以作为那些形成真正功能的组成的容器。

Transform :The Transform component determines the Position, Rotation, and Scale of each object in the scene. Every GameObject has a Transform.

翻译: 转换组件决定了场景中每个物体的位置、角度和大小。每一个游戏对象都有一个转换.

Component :Components are the nuts & bolts of objects and behaviors in a game. They are the functional pieces of every GameObject.

翻译: 组件是游戏中对象和行为的细节。它是每一个游戏对象的功能。

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

这一题没有图,不知道怎么分析

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

同上题没有办法分析.

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

5.1预设(Prefabs)有什么好处?

预设(Prefabs)的好处:

  • 预设是一个类模板,可以迅速方便创建大量相同属性的对象、操作简单,代码量少,减少出错概率.在设计时,可以直接从资源当中加载,成为一个游戏对象。同时如果要修改整体的属性对象,只需要修改预设就可以把全部的游戏对象的属性修改了.

5.2 预设与对象克隆 (clone or copy or Instantiate of Unity Object) 关系?

预设与克隆都能创建出相同的对象。预设一般和实例化的对象有关,而克隆出来的和被克隆的本土相互不影响.

5.3 制作 table 预制,写一段代码将 table 预制资源实例化成游戏对象

public GameObject temp = null;
void Start()
{
	GameObject test = (GameObject)Instantiate(temp);
	test.transform.position = new Vector3(0, Random.range(2,5),0);
	test.trainsform.parent = this.transform; 
}

2、 编程实践,小游戏

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

这是最后的展示效果.

3D游戏编程 离散仿真引擎基础-作业_第2张图片

接下来是对代码的一些讲解.

首先定义now_turn和state分别来保存现在是谁的回合和现在的棋盘信息.

第一个函数是reset函数

void reset()
{
    now_turn = 1;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            state[i, j] = 0;
        }
    }
}

这个函数是用来用来清空棋盘的,每次游戏开始之前都需要对棋盘进行清空.

然后设计了win_or_not函数,用来检查游戏是否结束了,如果√胜利那么返回1,如果x胜利,那么返回2,否则返回0.

int win_or_not()
{
	int[] flag = new int[]{1,1,1,1};
	for (int i = 0; i < 3; i++){
		for(int j = 0;j < 2;j++)
			flag[j] = 1;
		for (int j = 1; j < 3; j++){
			if (state [i , j] == 0 || state [i , j] != state[i , 0]){
				flag[0] = 0;
			}
		}
		if (flag[0] == 1)	return state [i , 0];
		for (int j = 1; j < 3; j++){
			if (state [j , i] == 0 || state [j , i] != state[0 , i]){
				flag[1] = 0;
			}
		}
		if (flag[1] == 1)	return state [0 , i];
		if(i > 0){
			if (flag[2] != 0 && state [i , i] != state [i - 1 ,i - 1]){
				flag[2] = 0;
			}
			if (flag[3] != 0 && state [i , 2 - i] != state [i - 1 ,3 - i]){
				flag[3] = 0;
			}
		}
	}
	if (flag[2] == 1 || flag[3] == 1) return state [1 , 1];
	return 0;
}

在设计这个函数时候,一开始在每次循环的时候没有对flag进行重新赋值,导致出现了一些问题,不过后面再debug的时候检查了出来.

最后是OnGUI函数,这个是对我们游戏整体UI的设计.

void OnGUI()
{
    GUI.Box(new Rect(496, 100, 160, 350), "");
    GUIStyle style = new GUIStyle ();
    style.normal.textColor = new Color (46f / 256f, 163f / 256f, 256f / 256f);
    style.fontSize = 32;
    if (GUI.Button (new Rect (525, 380, 100, 50), "reset")) {
        reset ();
    }
    int result = win_or_not ();
    if (result == 1) {
        GUI.Label (new Rect (530, 300, 100, 50), "√ win!!!", style);
    } else if (result == 2) {
        GUI.Label (new Rect (530, 300, 100, 50), "X win!!!", style);
    }
    int flag = 0;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if (state [i, j] == 0)
                flag = 1;
        }
    }
    if (flag == 0) {
        GUI.Label (new Rect (550, 300, 100, 50), "平局", style);
    }
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if (state [i, j] == 1) {
                GUI.Button (new Rect (i * 50+500, j * 50+100, 50, 50), "√");
            }
            if (state [i, j] == 2) {
                GUI.Button (new Rect (i * 50+500, j * 50+100, 50, 50), "X");
            }
            if (GUI.Button (new Rect (i * 50+500, j * 50+100, 50, 50), "")) {
                if (result == 0) {
                    if (now_turn == 1)
                        state [i, j] = 1;
                    else
                        state [i, j] = 2;
                    now_turn = -now_turn;
                }
            }
        }
    }
}

分别设计了底盘、9个可以点击的按钮和reset键。

这是最后演示视频的地址https://github.com/Don98/Web/blob/master/hw1/bandicam%202019-09-13%2017-15-05-188.mp4

你可能感兴趣的:(技术小白)