【Unity3D】離散仿真引擎基礎

1、簡答題

(1) 解釋 遊戲對象(GameObjects) 和 資源(Assets)的區別與聯繫。

遊戲對象是遊戲運行時出現在場景中的物體,它是一種容器,可以掛載各種各樣的組件。

而資源是指遊戲設計的過程中我們可以使用的一切物體和屬性。包括:網格、材質、代碼片段等。

資源是可以被遊戲對象使用的,一種資源可以被多個遊戲對象使用。

(2) 下載幾個遊戲案例,分別總結資源、對象組織的結構(指資源的目錄組織結構與遊戲對象樹的層次結構)

如圖,以Github上的一個遊戲案例【3D月光跑酷】爲例:
在這裏插入圖片描述
項目中最主要的是資源Assets文件夾,打開如下:
在這裏插入圖片描述
可以看到資源目錄下包含了音頻(Audio)、材質(Materials)、模型(Model)、代碼文件(Script)、場景(Scenes)、着色器(Shader)等等資源。其中Model文件夾存儲了主要的遊戲對象(GameObject),打開如下:
在這裏插入圖片描述
其中包含了玩家、建築、地板、硬幣等遊戲對象。

3. 編寫一個代碼,使用 debug 語句來驗證 MonoBehaviour 基本行爲或事件觸發的條件

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

代碼如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class NewBehaviourScript : MonoBehaviour {
	void Awake() {
		Debug.Log("Awake");
	}
	
	// 初始化
	void Start() {
		Debug.Log("Start");
	}
	
	// 每一幀進行一次刷新
	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");
	}
}

運行結果如下:
在這裏插入圖片描述
MonoBehaviour基本行爲或事件觸發的條件如下:

  • Awake() : 當前控制腳本實例被裝載的時候調用。一般用於初始化整個事例使用。
  • Start() : 當前控制腳本第一次執行Update之前調用。
  • Update() : 每幀都執行一次。
  • FixedUpdate() : 每固定幀繪製時執行一次,和Update不同的是FixedUpdate是渲染幀執行,如果你的渲染效率底下的時候FixedUpdate的調用次數就會下降。
  • LateUpdate() : 在每幀執行完畢調用。
  • OnEnable() : 當對象變爲可用或激活狀態時此函數被調用,OnEnable不能用於協同程序。
  • OnDisable() : 當對象變爲不可用或非激活狀態時此函數被調用。
  • OnGUI() : 繪製GUI時候觸發。

4. 查找腳本手冊,瞭解 GameObject,Transform,Component 對象

分別翻譯官方對三個對象的描述(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.

GameObjects是Unity中的基本對象,代表角色、道具和場景。它們本身不具有多少功能,但它們充當了組件的容器,由組件來實際實現功能。

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

Transform組件決定了遊戲對象的位置、旋轉與縮放比例。每一個遊戲對象都有Transform組件。

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

Component遊戲中對象和行爲的細節。他們是每個遊戲對象的功能部分。

描述下圖中 table 對象(實體)的屬性、table 的 Transform 的屬性、 table 的部件

本題目要求是把可視化圖形編程界面與 Unity API 對應起來,當你在 Inspector 面板上每一個內容,應該知道對應 API。

  • table對象(實體)的屬性:Tag、Layer
  • table的Transform屬性:Position、Rotation、Scale
  • table的部件:Mesh Filter、Box Collider、Mesh Renderer
用 UML 圖描述三者的關係

在這裏插入圖片描述

5. 資源預設(Prefabs)與 對象克隆 (clone)

預設(Prefabs)有什麼好處?

預設是組件的集合體,預設的物體可以實例化成爲遊戲對象。預設可以重複地創建具有相同結構的遊戲對象,便於批量處理。

預設與對象克隆 (clone or copy or Instantiate of Unity Object) 關係?

克隆遊戲對象需要場景中有被克隆對象,而創建預製只需事先創建預製即可,允許場景中一開始並不存在該遊戲對象。

克隆出來的遊戲對象並不會隨着被克隆體的變化而發生變化,但是使用預製創建出來的對象會隨着預製的改變而發生改變。

製作 table 預製,寫一段代碼將 table 預製資源實例化成遊戲對象
 void Start () {  
        GameObject anotherTable = (GameObject)Instantiate(table.gameObject);  
    }

2、 編程實踐,小遊戲

井字棋

變量聲明:

private int turn = 1;   //1表示O的回合,-1表示X的回合
private int[,] state = new int[3, 3];  //棋盤該處的狀態,0爲空,1爲O,2爲X

start函數:

// Start is called before the first frame update
void Start()
{
    Reset();
}

創建GUI界面:利用循環創建Buttons

void OnGUI()
{
    if (GUI.Button(new Rect(Screen.width / 2 - 45, Screen.height / 2 + 130, 100, 50), "RESTART"))
        Reset();
    int result = checkResult();
    if (result == 1)
    {
        GUI.Label(new Rect(Screen.width / 2 - 20, Screen.height / 2 + 75, 100, 50), "O WINS!");
    }
    else if (result == 2)
    {
        GUI.Label(new Rect(Screen.width / 2 - 20, Screen.height / 2 + 75, 100, 50), "X WINS!");
    }
    else if (result == 3)
    {
        GUI.Label(new Rect(Screen.width / 2 - 20, Screen.height / 2 + 75, 100, 50), "   Tie! ");
    }
    
    for (int i = 0; i < 3; ++i)
    {
        for (int j = 0; j < 3; ++j)
        {
            if (state[i, j] == 1)
                GUI.Button(new Rect(Screen.width / 2 - 75 + 50 * i, Screen.height / 2 - 130 + 50 * j, 50, 50), "O");
            if (state[i, j] == 2)
                GUI.Button(new Rect(Screen.width / 2 - 75 + 50 * i, Screen.height / 2 - 130 + 50 * j, 50, 50), "X");
            if (GUI.Button(new Rect(Screen.width / 2 - 75 + 50 * i, Screen.height / 2 - 130 + 50 * j, 50, 50), ""))
            {
                if (result == 0)
                {
                    if (turn == 1)
                        state[i, j] = 1;
                    else
                        state[i, j] = 2;
                    turn = -turn;
                }
            }
        }
    }
}

重置函數Reset:

// 初始化
void Reset()
{
    turn = 1;
    for (int i = 0; i < 3; ++i)
    {
        for (int j = 0; j < 3; ++j)
        {
            state[i, j] = 0;
        }
    }
}

通過循環檢查state來判斷結果:

int checkResult()
{
    // 橫
    for (int i = 0; i < 3; ++i)
    {
        if (state[i, 0] != 0 && state[i, 0] == state[i, 1] && state[i, 1] == state[i, 2])
        {
            return state[i, 0];
        }
    }
    // 豎
    for (int i = 0; i < 3; ++i)
    {
        if (state[0, i] != 0 && state[0, i] == state[1, i] && state[1, i] == state[2, i])
        {
            return state[0, i];
        }
    }
    // 斜
    if (state[1, 1] != 0 &&
        state[0, 0] == state[1, 1] && state[1, 1] == state[2, 2] ||
        state[0, 2] == state[1, 1] && state[1, 1] == state[2, 0])
    {
        return state[1, 1];
    }

    // 平局
    int count = 0;
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            if (state[i, j] != 0)
            {
                count++;
            }
        }
    }
    if (count == 9)
    {
        return 3;
    }
    return 0;
}
遊戲界面

在這裏插入圖片描述
在這裏插入圖片描述

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