您當前的位置:首頁 > 繪畫

Unity中GameObject API解析

作者:由 大智 發表于 繪畫時間:2018-08-07

本文節選自

洪流學堂

公眾號專欄《鄭洪智的Unity2018課》,未經允許不可轉載。

洪流學堂

公眾號回覆

專欄

,檢視更多專欄文章。

洪流學堂,讓你快人幾步。你好,我是鄭洪智。

GameObject我們已經很瞭解了,它本身沒有功能,它是元件的容器,很多時候我們需要在指令碼中操作GameObject。今天我們就來看看如何實現這些需求。

GameObejct相關的文件位於:

https://

docs。unity3d。com/Script

Reference/GameObject。html

這一篇我們會採用問題+答案的形式,告訴你如何解決遊戲中常見的需求。

如何在指令碼中獲取自身所在的GameObject?

我們知道指令碼必須掛在一個GameObject上面才能執行,那麼如何知道當前指令碼所掛載的GameObject是哪一個呢?

這就需要用到

gameObject

屬性了。

gameObject

屬性可以在所有繼承MonoBehaviour的類中獲取到,因為指令碼必須要掛在到一個物體上才能執行,這個gameObject就是指令碼掛到的物體。

using

UnityEngine

public

class

Test

MonoBehaviour

{

void

Start

()

{

Debug

Log

gameObject

name

gameObject

);

}

}

上面的程式碼就會打印出指令碼所掛物體的名字。

注意這裡Debug。Log傳入了兩個引數,這是為什麼呢?

遇到這種問題,我們首先查一下Unity的文件。

為什麼要查

Unity

的文件呢?

Unity中GameObject API解析

從圖中可以看到,將游標移到Debug上面時,顯示Debug類是屬於UnityEngine這個名稱空間的,也就是Unity提供的API。

Debug。Log有兩種形式:

public

static

void

Log

object

message

);

public

static

void

Log

object

message

Object

context

);

第二種形式中可以傳入一個Object型別的引數,傳入這個引數時,在Console中顯示的log會與指令碼所在的物體關聯。點選Console中這條資訊時,會在Hierarchy中高亮這一個物體。

Unity中GameObject API解析

Log關聯GameObject。gif

如何透過物體名字查詢物體?

GameObject類中有一個靜態(static)方法Find,用於透過名字查詢場景中的物體。

什麼是

靜態方法

靜態方法是標記為static的方法。靜態方法獨立於例項物件存在。即使沒有類的例項,仍然可以透過類名。靜態方法呼叫。

靜態方法中不能訪問例項成員,可以訪問其他靜態成員

靜態方法在定義時需要在返回值型別前面加上static修飾符,比如:

static

void

Walk

(){

Debug

Log

“Walking”

);

}

訪問時,可以直接透過

類名。方法名

呼叫。比如查詢物體的方法就是

GameObject。Find(“cat”)

查詢的名稱字串中可以包含“/”,比如

GameObject。Find(“animals/cat”)

就只會查到父物體名字為animals的cat物體。如果“/”字元在字串中最開始的位置,那麼會在根節點開始找,比如

GameObject。Find(“/animals/cat”)

就只會查到根節點為animals物體的子物體cat。

查詢過後,一定要判斷一下是否為空,因為Find有可能找不到你想找的物體。

特別注意1

這個方法的效率比較低,不要在Update中呼叫此方法,否則可能會造成遊戲卡頓。一般的做法是,在Awake或Start方法中透過Find找到,然後儲存到成員變數中。

比如:

using

UnityEngine

public

class

Test

MonoBehaviour

{

private

GameObject

cat

void

Start

()

{

cat

=

GameObject

Find

“cat”

);

if

cat

!=

null

Debug

Log

“找到了cat物體”

cat

);

}

}

特別注意2

這個方法無法找到active為false的物體。

那麼如何查詢active為false的物體呢?

1、不要使用Find,直接在程式碼中透過public的變數關聯物體。

2、不要設定物體的active為false,先在遊戲最開始時透過程式碼找到物體,然後透過程式碼設為false

3、透過transform。Find,我們明天會講到。

如何修改物體的active狀態?

修改物體的active狀態是一個快速隱藏/顯示物體的方法。物體的active是false時,物體上

所有的元件都不會執行

,相當於將物體隱藏了。

gameObject。SetActive

false

特別注意

這個方法只會改變物體自身的active屬性。如果該物體有子物體,那麼子物體也會被隱藏,但是active屬性不會變。如果該物體的父物體的active是false,即使將該物體的active設定為true,該物體也不會顯示出來。

物體的active可以透過兩個屬性來判斷:

activeInHierarchy

物體是否在Hierarchy中是啟用狀態。這個屬性為true時,該物體及其所有父物體的active都為true。

activeSelf

物體自身的active屬性是否為true,即使該物體的父物體的active可能為false。

如何透過tag查詢物體?

除了透過物體的name查詢物體,透過物體的tag也可以查詢。Tag即在Inspector上設定的一個標籤,如下圖所示:

Unity中GameObject API解析

一個物體只能有一個Tag,但是一個Tag可以被多個物體使用。

透過tag查詢有兩個方法:

public

static

GameObject

FindWithTag

string

tag

);

返回

第一個

查詢到的標籤為tag的active為true的物體,如果沒有找到則返回null。

tag必須在TagManager中設定過,否則會丟擲異常。異常內容是:

UnityException: Tag: cat is not defined。

含義是:

標籤:cat 沒有定義

public

static

GameObject

[]

FindGameObjectsWithTag

string

tag

);

由於一個Tag可以被多個物體使用,所以這個方法可以找到所有使用該標籤的active為true的物體,並返回對應的陣列。如果沒有找到,會返回一個空陣列(長度為0的陣列)。

tag必須在TagManager中設定過,否則會丟擲異常。異常內容是:

UnityException: Tag: xxx is not defined。

含義是:

標籤:xxx 沒有定義

如何用程式碼建立空物體?

有時候為了組織Hierarchy的結構,需要動態建立空物體作為資料夾使用。

建立空物體可以使用如下程式碼:

GameObject

go

=

new

GameObject

();

go

name

=

“EmptyGameObject”

GameObject

dog

=

new

GameObject

“Puppy”

);

new的時候可以傳入一個字串作為GameObject的名字。也可以不傳,預設名字是

New Game Object

。也可以建立後再修改空物體的名字。

如何用程式碼建立內建幾何體?

透過程式碼也很容易建立Unity中的幾種預設幾何體。

public

static

GameObject

CreatePrimitive

PrimitiveType

type

);

其中PrimitiveType是一個列舉(enum)型別,包括的型別有:Sphere、Capsule、Cylinder、Cube、Plane、Quad。

具體的用法如下:

GameObject cube = GameObject。CreatePrimitive(PrimitiveType。Cube);

上面的程式碼可以建立一個Cube,和透過選單欄

GameObject

>

3D Object

>

Cube

創建出來的Cube一致。

什麼是

列舉

列舉是一組命名整型常量。列舉型別是使用 enum 關鍵字宣告的。

C# 列舉是值型別。換句話說,列舉包含自己的值,且不能繼承或傳遞繼承。

宣告列舉的一般語法:

enum

<

enum_name

>

{

enumeration

list

};

其中,

enum_name 指定列舉的型別名稱。

enumeration list 是一個用逗號分隔的識別符號列表。

列舉列表中的每個符號代表一個整數值,一個比它前面的符號大的整數值。預設情況下,第一個列舉符號的值是 0。例如:

enum

Days

{

Sun

Mon

tue

Wed

thu

Fri

Sat

};

使用時,可以使用

Days。Sun

來表示星期日。

總結

本文講解了和GameObject類相關的常見問題及API的用法。

但是由於GameObject類中還有一些不常用API,建議自行查閱GameObject文件獲得更全面的瞭解:

https://

docs。unity3d。com/Script

Reference/GameObject。html

今日思考題

在Unity中透過程式碼嘗試下講到的和沒講到的API~

歡迎在留言區分享你的收穫,和大家一起討論。

別忘了分享給你學Unity的朋友,也許能夠幫到他。

洪流學堂

公眾號回覆

專欄

,檢視更多專欄文章。

標簽: 物體  GameObject  Active  cat  列舉