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

最後的結果爲:
在這裏插入圖片描述

我們可以看得到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 文檔能力

這是最後的展示效果.

在這裏插入圖片描述

接下來是對代碼的一些講解.

首先定義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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章