1、簡答題
-
解釋 遊戲對象(GameObjects) 和 資源(Assets)的區別與聯繫。
-
遊戲對象是遊戲中具有一定屬性、參數、構件的一種對象,它可以是一個場景,一個角色,一個裝備等。
-
資源指的是在遊戲中使用到的模型、聲音文件、貼圖文件等等。
-
兩者之間的聯繫:資源可以構成遊戲對象,遊戲對象也可以作爲資源。
-
-
下載幾個遊戲案例,分別總結資源、對象組織的結構(指資源的目錄組織結構與遊戲對象樹的層次結構)
遊戲案例AngryBots- 資源的結構
項目中的各種資源按照Animations、Editor等等各種類別分別進行歸類,每一類資源都放置在對應的子文件夾中。 - 對象組織的結構
每一個大的對象都是由若干個具體的小對象進行組合得到的,每一個小對象可以構成很多個不同的大對象。這種構成方法可以由大到小逐步構成一個複雜的遊戲對象。
- 資源的結構
-
編寫一個代碼,使用 debug 語句來驗證 MonoBehaviour 基本行爲或事件觸發的條件
基本行爲包括 Awake() Start() Update() FixedUpdate() LateUpdate()
常用事件包括 OnGUI() OnDisable() OnEnable()
查找腳本手冊,瞭解 GameObject,Transform,Component 對象- Awake:在載入Script的時候執行對應代碼
- Start:在所有的Update之前被調用
- Update:固定每一幀進行調用
- FixedUpdate:間隔固定的時間進行一次執行,而不是依賴於幀數。
- LateUpdate:每一幀進行一次調用,它會在所有Update之後執行。
- Ongui:在每一次渲染或者操作GUI時執行調用。
- OnDisable:在行爲被disable的時候進行調用。
- OnEnable:在行爲被enable的時候進行調用。
可以看出調用了Awake、Enable、Start等之後,每一幀都進行了Update
最後停止執行的時候調用了Disable
執行代碼:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FirstBeh : MonoBehaviour {
// Use this for initialization
void Start () {
Debug.Log("This Start!");
}
// Update is called once per frame
void Update () {
Debug.Log("This Update!");
}
void OnEnable () {
Debug.Log("This Enabled!");
}
void OnDisable () {
Debug.Log("This Disabled!");
}
void Awake(){
Debug.Log("This Awake!");
}
void FixedUpdate()
{
Debug.Log("This FixedUpdate!");
}
void LateUpdate()
{
Debug.Log("This LateUpdate!");
}
}
-
查找腳本手冊,瞭解 GameObject,Transform,Component 對象
-
分別翻譯官方對三個對象的描述(Description)
GameObject:所有遊戲元素的基礎。
Transform:對遊戲對象的移動、旋轉、放縮
Component:和遊戲對象相聯繫的基礎類 -
描述下圖中 table 對象(實體)的屬性、table 的 Transform 的屬性、 table 的部件
ActiveSelf:定義對象的名稱和活動狀態。
Transform:定義對象的位置,角度,放縮
BoxCollider:調整座標系的位置和放縮
Component:對象的相關組件
-
-
本題目要求是把可視化圖形編程界面與 Unity API 對應起來,當你在 Inspector 面板上每一個內容,應該知道對應 API。
例如:table 的對象是 GameObject,第一個選擇框是 activeSelf 屬性。
用 UML 圖描述 三者的關係(請使用 UMLet 14.1.1 stand-alone版本出圖)
-
整理相關學習資料,編寫簡單代碼驗證以下技術的實現:
查找對象
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Scr : MonoBehaviour {
// Use this for initialization
void Start () {
var obj = GameObject.Find("Table");
Debug.Log(obj);
}
// Update is called once per frame
void Update () {
}
}
通過GameObject.Find可以查找到具有對應ID的圖像。
添加子對象
通過CreatePrimitive函數,新建一個特定類型的對象。使用新建對象的transform.parent,修改對象的parent關係。
遍歷對象樹
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Scr : MonoBehaviour {
// Use this for initialization
void Start () {
var obj = GameObject.Find("Table");
Debug.Log(obj);
GameObject subele = GameObject.CreatePrimitive(PrimitiveType.Cube);
subele.name = "sub";
subele.transform.position = new Vector3(0,3,0);
subele.transform.parent = obj.transform;
var trans = obj.transform;
foreach(Transform sub in trans)
{
Debug.Log(sub.name);
}
}
// Update is called once per frame
void Update () {
}
}
使用forech遍歷子對象
清除所有子對象
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Scr : MonoBehaviour {
// Use this for initialization
void Start () {
var obj = GameObject.Find("Table");
Debug.Log(obj);
GameObject subele = GameObject.CreatePrimitive(PrimitiveType.Cube);
subele.name = "sub";
subele.transform.position = new Vector3(0,3,0);
subele.transform.parent = obj.transform;
var trans = obj.transform;
foreach(Transform sub in trans)
{
Debug.Log(sub.name);
Destroy(sub.gameObject);
}
}
// Update is called once per frame
void Update () {
}
}
-
資源預設(Prefabs)與 對象克隆 (clone)
- 預設(Prefabs)有什麼好處?
預設將已經設計好的對象進行封裝,在後續的設計開發過程中直接導入項目當中,更加貼合面向對象的設計要求,設計過程更加便捷。 - 預設與對象克隆 (clone or copy or Instantiate of Unity Object) 關係?
克隆是指將已經存在的對象進行復制,複製的對象也可以是預設。預設可以爲克隆提供一個非常好的模板。
- 預設(Prefabs)有什麼好處?
-
製作 table 預製,寫一段代碼將 table 預製資源實例化成遊戲對象
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LoadBeh : MonoBehaviour {
public Transform res;
// Use this for initialization
void Start () {
// Load Resources
Object table = Resources.Load("Table");
GameObject newobj = Instantiate(table) as GameObject;
newobj.transform.position = new Vector3 (0, Random.Range (-5, 5), 0);
newobj.transform.parent = this.transform;
}
}
通過load對應的預設元素,進行復制之後重新調整位置。
- 井字棋
通過利用GUI事件和創建GUI Lebel和Button的方法,可以完成本次任務。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GG : MonoBehaviour {
int[, ] board = new int[3, 3];
int turn;
int remain = 9;
int judge () {
if (board[1, 1] == board[1, 0] && board[1, 1] == board[1, 2] && 0 != board[1, 1]) return board[1, 1];
if (board[1, 1] == board[0, 1] && board[1, 1] == board[2, 1] && 0 != board[1, 1]) return board[1, 1];
if (board[1, 1] == board[0, 0] && board[1, 1] == board[2, 2] && 0 != board[1, 1]) return board[1, 1];
if (board[1, 1] == board[2, 0] && board[1, 1] == board[0, 2] && 0 != board[1, 1]) return board[1, 1];
if (board[0, 0] == board[1, 0] && board[1, 0] == board[2, 0] && 0 != board[1, 0]) return board[1, 0];
if (board[0, 0] == board[0, 1] && board[0, 1] == board[0, 2] && 0 != board[0, 1]) return board[0, 1];
if (board[2, 2] == board[1, 2] && board[1, 2] == board[0, 2] && 0 != board[1, 2]) return board[1, 2];
if (board[2, 2] == board[2, 1] && board[2, 1] == board[2, 0] && 0 != board[2, 1]) return board[2, 1];
if (remain == 0) return 2;
return 0;
}
// Use this for initialization
void Start () {
reset ();
}
void reset () {
turn = 1;
int i, j;
for (i = 0; i <= 2; ++i)
for (j = 0; j <= 2; ++j)
board[i, j] = 0;
remain = 9;
}
void showRes () {
if (judge () == 1)
GUI.Label (new Rect (420 , 20, 100, 80), "O is winner!");
else if (judge () == -1)
GUI.Label (new Rect (420 , 20, 100, 80), "X is winner!");
else if (judge () == 2)
GUI.Label (new Rect (420 , 20, 100, 80), "Draw!");
else GUI.Label (new Rect (420 , 20, 100, 80), "Running!");
}
void OnGUI () {
if (GUI.Button (new Rect (400 , 450, 100, 80), "Reset")) {
Start ();
}
showRes ();
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++) {
if (board[i, j] == 1) GUI.Button (new Rect (i * 100 + 300, j * 100 + 100, 100, 100), "O");
if (board[i, j] == -1) GUI.Button (new Rect (i * 100 + 300, j * 100 + 100, 100, 100), "X");
// if (board[i, j] == 0) GUI.Button (new Rect (i * 100 + 400, j * 100 + 80, 100, 100), "");
if (GUI.Button (new Rect (i * 100 + 300, j * 100+ 100, 100, 100), "")) {
if (judge () == 0 && board[i, j] == 0) {
board[i, j] = turn;
remain--;
turn = -turn;
showRes ();
}
}
}
}
// Update is called once per frame
void Update () {
}
}