基礎(chǔ)知識:
Transform作為Unity中游戲?qū)ο笞顬橹匾慕M件悼院,“位置”作為Transfrom組件的一個屬性战虏,具有同等重要的地位。
Transform組件下有兩個“位置”屬性:
position:指的是游戲?qū)ο笾行狞c(diǎn)在世界空間的位置(世界空間就是Unity最大的空間,可以創(chuàng)建一個無任何父節(jié)點(diǎn)的空對象井佑,其position,rotation分量都是0草巡,scale分量都是1守呜,那么可以認(rèn)為世界空間就是以此物體中心點(diǎn)為原點(diǎn),物體的朝向為z軸山憨,右方向為x軸弛饭,上方向為y軸,即物體的transform.forward為z軸萍歉,transform.right為x軸侣颂,transform.up為y軸,如圖中的SuperParent物體)。
localPosition:指的是游戲?qū)ο笾行狞c(diǎn)在父類空間的位置(屬性面板上顯示的值就是這個值)枪孩。
父類空間的構(gòu)建與其position,rotation,scale有關(guān)憔晒,但此處只討論position,因此可以認(rèn)為父類物體不旋轉(zhuǎn)蔑舞,沒有縮放的情況拒担。那么此時父類空間是以父類中心點(diǎn)為原點(diǎn),x,y,z與世界空間x,y,z軸同方向攻询。
如果游戲?qū)ο鬀]有父類从撼,那么此物體的父類空間就是世界空間,此時position和localPosition值是相同的钧栖〉土悖可以想象為,其父類就是文章上面的SuperParent物體拯杠。
UGUI下所有的UI空間都具有RectTransform組件掏婶,此組件繼承自Transform組件,其內(nèi)部的position和localPosition屬性也繼承自Transform潭陪。他多出來的位置屬性是:
anchoredPosition3D:指的是物體中心點(diǎn)Pivot相對于錨點(diǎn)Anchor的位置(UI屬性面板上顯示的就是這個值雄妥,即PosX最蕾,PosY,PosZ)老厌。
注意:
1瘟则、 這里指的是錨點(diǎn),盡管錨點(diǎn)是附加在父類上的枝秤,但其并不是父類空間醋拧,父類空間指的是以其中心點(diǎn)為原點(diǎn),而此處指的是以錨點(diǎn)為原點(diǎn)宿百。
2趁仙、 RectTransform提供了我們足夠的自由去更改UI的錨點(diǎn)位置和中心點(diǎn)的位置。但是萬變不離其宗:anchoredPosition3D核心概念沒變:中心點(diǎn)相對錨點(diǎn)的位置垦页。
3雀费、 anchoredPosition是anchoredPosition3D屬性去除了z軸之后的值。
擴(kuò)展知識:
盡管上述概念都是大家耳熟能詳?shù)臇|西痊焊,有關(guān)的博文一搜一大堆盏袄,我為什么要再總結(jié)一篇大家都知道的東西呢?因為看似簡單的東西薄啥,可以做出復(fù)雜的系統(tǒng)辕羽,看似復(fù)雜的東西,都是由簡單的東西堆砌出來的垄惧。
重點(diǎn)來了:位置脫離了空間系統(tǒng)毫無意義刁愿。人盡皆知啊。接下來請牢記:位置計算一定要統(tǒng)一空間到逊。
Unity中铣口,游戲物體除了有本地位置,世界空間位置觉壶,還有相對攝像機(jī)的位置(視角空間位置)脑题,屏幕空間位置。其中的轉(zhuǎn)換詳情計算機(jī)圖形學(xué)铜靶,以后我也會總結(jié)有關(guān)圖形學(xué)的知識叔遂。
實(shí)戰(zhàn):
最后用一個例子介紹一下這些位置的用途。
王者榮耀英雄展示界面争剿。一邊為英雄模型已艰,一邊為UI顯示英雄技能等信息,是怎么樣做到的模型跟正好顯示在了規(guī)定的地方秒梅。如圖:
兩個接口(Camera組件下):
public Vector3 WorldToScreenPoint(Vector3 position);
//輸入物體世界空間坐標(biāo)得到物體當(dāng)前攝像機(jī)下屏幕空間坐標(biāo)位置
public Vector3 ScreenToWorldPoint(Vector3 position);
//輸入物體當(dāng)前攝像機(jī)下屏幕空間坐標(biāo)得到物體世界空間坐標(biāo)位置
注意:
1旗芬、屏幕空間坐標(biāo)依賴于攝像機(jī)。同一物體捆蜀,在不同攝像機(jī)下,其得到的屏幕坐標(biāo)是不同的。不懂的話辆它,可以了解一下圖形學(xué)坐標(biāo)轉(zhuǎn)換誊薄。
2、屏幕空間坐標(biāo)是三維的锰茉。其x,y軸是指顯示在屏幕上的位置呢蔫,z軸具有特殊意義——物體的深度值(與物體距離攝像機(jī)的遠(yuǎn)近有關(guān))。
Camera組件下有很對關(guān)于空間位置的計算飒筑。有興趣的話片吊,可以研究研究。
首先我們需要兩個攝像機(jī):一個UI攝像機(jī)顯示UI协屡,一個模型攝像機(jī)顯示模型俏脊。
具體思路:由UI位置計算其屏幕坐標(biāo)位置,再由屏幕坐標(biāo)位置計算模型世界空間位置肤晓。
場景:一個button爷贫,button下有一個位置標(biāo)識,通過我點(diǎn)擊button补憾,會在該位置標(biāo)識上生成一個小球(這個button同時充當(dāng)了模型展臺漫萄,小球就是宮本。太low了盈匾,哈哈)腾务,game場景如下:
代碼如下:
public GameObject prefab; //小球預(yù)制件
public Camera uiCamera; //UI攝像機(jī)
public Camera modelCamera; //模型攝像機(jī)
public GameObject posTag; //需要把模型放置的位置
public int z = 5; //修改屏幕坐標(biāo)的Z軸
public void ClickButton()
{
//初始化物體
GameObject go = GameObject.Instantiate(prefab);
Vector3 showPos = posTag.transform.position;
//獲取展示位置的屏幕空間坐標(biāo)
Vector3 screenPos = uiCamera.WorldToScreenPoint(showPos);
//設(shè)置屏幕坐標(biāo)的z軸。z軸代表物體的深度值削饵,與距離攝像機(jī)的遠(yuǎn)近有關(guān)岩瘦。
//可以調(diào)一下大小感受一下
screenPos.z = z;
//獲取模型攝像機(jī)下得到同一屏幕空間坐標(biāo)的世界空間坐標(biāo)
Vector3 modelPos = modelCamera.ScreenToWorldPoint(screenPos);
go.transform.position = modelPos;
}
效果展示:
位置不對啊葵孤?其實(shí)是因為所有的坐標(biāo)都是以中心點(diǎn)為基礎(chǔ)的担钮。小球的中心點(diǎn)在圓心,所以小球的中心點(diǎn)是與標(biāo)志物重合的尤仍。在游戲中箫津,美術(shù)提交的模型中心點(diǎn)基本都會設(shè)置在人物腳上,所以就不會出現(xiàn)這個情況宰啦。
小結(jié):
知識點(diǎn):位置概念不能脫離空間苏遥。位置計算一定要統(tǒng)一空間。