您好,登錄后才能下訂單哦!
每個游戲對象(GameObject),其存在于游戲世界,都有一個位置、朝向、大小等基本定位信息;其存于Hierarchy面板,也存在與其他GameObject的相對關系,如父子關系、兄弟關系。Unity中使用Transform來描述和操作這些屬性。
Transform的字面理解就是“變換”的意思,所有的GameObject,當其被創建完成之后,均自動創建了這樣一個變換組件,你不需要手動創建這個組件,而且無法刪除此組件。
接下來,我們將變換組件的主要屬性和功能一一進行解釋。
層次面板
childCount:代表當前GameObject節點下方有幾個子節點
hierarchyCount:代表在當前GameObject所處的相互關聯的樹狀結構中,存在的層次數目。
相互關聯的樹狀結構指的是:以Hierarchy面板中的一個頂層GameObject作為根節點出發的一棵樹。任何一個GameObject都會存在于一棵樹中。
可以預想的是,這個樹狀結構中的任意一個節點的hierarchyCount屬性都是相同的。
hierarchyCapacity:代表當前所在的樹的層次容量。就是這棵樹最大可以容納的節點數目,從整個樹中的任意一個節點訪問此屬性,所獲取的層次容量都是相同的。
這個參數是自動增長的,即當GameObject發生層次變動時,如果當前樹的容量不足,會自動擴容。
可以推測出:樹中所有節點所查詢的結果實際來自最頂層節點的屬性,而當層次所發生變動時,Unity內部只需要修改頂層節點的這個屬性即可。
需要注意的是,當頻繁變化hierarchyCapacity時,是需要帶來額外的內存消耗和性能消耗的,這與List類的內存擴容是一個道理。因此,應該為頻繁增長的樹的根節點在一開始就設置一個比較大的容量。
parent:代表當前節點的父節點,返回一個Transform對象。當此parent為null時,就代表自己已經是頂層節點,也即樹狀結構中的根節點了。
root:獲得當前樹狀結構中的根節點。
DetachChildren():分離子節點,意思就是將當前節點下方的所有直接子節點都分離出去,讓他們成為根節點。有n個子節點,將產生n棵新的樹。
Find(string name):根據路徑查找子節點,雖然這里的參數在文檔上顯示為name,但是它實際代表一個路徑。它可以是"magazine/ammo"這種格式,即可以向著葉節點深度方向查詢多個層次,找到目標Transform并返回。如果找不到返回空。
GetChild(int index):根據索引index,返回當前節點的直接子節點。
GetSiblingIndex():獲得當前節點處于其父節點下的編號索引,即處于兄弟列表中的Index。
SetAsFirstSibling():設置當前節點為兄弟節點列表中的第一個節點。
SetAsLastSibling():設置當前節點為兄弟節點列表中的最后一個節點。
SetSiblingIndex(int index):將當前節點設置到其兄弟列表中的index位置。
SetParent(Transform parent, bool worldPositionStays):設置當前節點的父節點,如果worldPositionStays設置為true,則保持其世界坐標下的位置、旋轉和縮放。這會相應地修改其局部坐標、旋轉和縮放信息。(后續章節會涉及到世界和局部坐標的概念)
這里所說的變換,就是指所處的位置、旋轉(朝向)、縮放(大小)等信息。
Unity下的單位是米,比如你新建一個Cube,那么它默認的尺寸是1x1x1的尺寸,那么我們想要設置這個Cube到需要的尺寸,只要修改它的Trasform下的Scale三維向量參數即可,它代表了在1x1x1這個基礎上所進行的縮放。
那些從外部導入的三維模型對象,它本身就帶有一個局部的坐標系,和這個三維對象相對此局部坐標系的尺寸和位置。若要修改它的尺寸,則是基于此對象在其導入的局部坐標系中的尺寸和位置為基礎,進行相應的縮放。
由于一棵樹代表了很多個層次的存在,每個節點均有自己的縮放、旋轉、位置等信息。而且子節點的變換狀態會跟隨父節點變換狀態的變化而改變,因此Unity中存在局部坐標和全局坐標的概念。局部坐標是指其相對直接父節點的變換信息,而全局坐標是指當前節點疊加了所有父節點的累積變換之后的狀態結果。
接下來詳細了解變換相關的屬性和方法。
Vector3 localPosition:局部坐標系下的位置
Vector3 position:全局坐標系下的位置
Quaternion localRotation:局部坐標系下的旋轉
Quaternion rotation:全局坐標系下的旋轉
Vector3 localScale:局部坐標系下的縮放
Vector3 lossyScale:全局坐標系下的縮放
Vector3 localEulerAngles:局部坐標系下的歐拉角
Vector3 eulerAngles 全局坐標系下的歐拉角
Vector3 forward:全局坐標系下的前方矢量
Vector3 up:全局坐標系下的上方矢量
Vector3 right:全局坐標系下的右方矢量
通過以上屬性看出,都每個變換屬性都有局部和全局之分。位置和縮放比較容易理解。不過縮放有兩種表現形式,一種是歐拉角,一種是四元數,實際上四元數也就是使用歐拉角在進行計算。對于這部分數學不熟悉的同學不必緊張,我們不需要詳細了解四元數的原理,只要學會使用即可。后續的章節中我們會慢慢熟悉四元數的一些用法,而對于歐拉角,我們只要簡單知道其概念即可:歐拉角是用相對Z、X、Y軸旋轉一定的度數來表示旋轉的一種方法,請記住它是按照先Z、再X、再Y這個順序進行旋轉的。
Unity文檔上講到,如果你對于歐拉角不是很熟悉,就不要使用它,四元數可以滿足你的要求了。而實際上我們對于簡單一些旋轉計算,使用歐拉角是更方便的,速度也更快,比如,我們只需要某個物體相對其父節點圍繞X、Y、Z中的單一軸進行旋轉,此時文檔相對簡單,我們可以使用歐拉角進行處理,稍微復雜一點的情況,后面的四元數章節在做解釋。
另外需要注意幾點:
1、Vector、Quaternion 都是結構體,通過localRotation、position等以上函數獲取的結果都是存在一個結構體中的,此時的返回結果是存在單獨開辟的新內存中的,因此對其直接修改不能影響其原有數值,我們必須以localRotation=Vector這種形式對其賦值,讓其進行函數內進行實際賦值操作。
2、Transform也是一個組件,盡管每個GameObject類中都有transform這個成員,但其內部實現依然是getComponent的函數調用,而這種函數調用是比較耗時的,考慮到頻繁需要對Transform進行操作,因此,我們應該在腳本的初始化過程中獲取一個Transform引用并保留下來,以便后續調用而避免頻繁使用到getComponent。這也是上一節代碼中我們這樣做的目的。
本文為博主原創文章,歡迎轉載。請保留博主鏈接http://blog.csdn.net/andrewfan
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。