說說Unity3D里的各種坐標(biāo)系

一、Unity3D中有哪些坐標(biāo)系屿聋?

坐標(biāo)系這個(gè)概念最早是由法國數(shù)學(xué)家笛卡爾提出的咧欣,并由此創(chuàng)造了用代數(shù)方法來研究幾何圖形的數(shù)學(xué)分支——解析幾何。解析幾何的基本思想是將幾何圖形抽象成點(diǎn)的運(yùn)動(dòng)軌跡,從而點(diǎn)可以作為組成圖形的基本元素皮假,而描述一個(gè)點(diǎn)的位置首先需要建立合適的坐標(biāo)系鞋拟。所以,首先我們來了解下Unity3D中都有哪些坐標(biāo)系吧惹资!Unity3D中的坐標(biāo)系目前可以分為以下四類:世界坐標(biāo)贺纲、屏幕坐標(biāo)、視圖坐標(biāo)和GUI坐標(biāo)褪测。下面我們來對(duì)這5類坐標(biāo)進(jìn)行詳細(xì)說明:

世界坐標(biāo)

世界坐標(biāo)按照笛卡爾坐標(biāo)系定義出來的絕對(duì)坐標(biāo)系猴誊,下面的各種坐標(biāo)系都建立在世界坐標(biāo)的基礎(chǔ)上。我們知道二維平面內(nèi)任意一個(gè)點(diǎn)可以用二維坐標(biāo)(x,y)來表示侮措,如果將這個(gè)概念延伸到三維空間內(nèi)懈叹,那么三維空間內(nèi)任意一個(gè)點(diǎn)都可以用三維坐標(biāo)(x,y,z)來表示。這就是世界坐標(biāo)的概念啦分扎,坐標(biāo)系通吵纬桑可以分為左手坐標(biāo)系和右手坐標(biāo)系,而Unity3D采用的是左手坐標(biāo)系畏吓。在Unity3D中我們可以使用transform.position來獲取場(chǎng)景中一個(gè)物體的世界坐標(biāo)墨状,通常情況下編輯器中的Inspector窗口是以世界坐標(biāo)來描述一個(gè)3D物體的位置的,除非當(dāng)一個(gè)3D物體存在父物體的時(shí)候菲饼,它會(huì)以相對(duì)坐標(biāo)來描述其位置歉胶。

屏幕坐標(biāo)

屏幕坐標(biāo)是以像素來定義的,它的范圍是以左下角為(0,0)巴粪,右上角為(Screen.width,Screen.height)定義的這樣一個(gè)矩形通今。屏幕坐標(biāo)是一個(gè)3D坐標(biāo),Z軸是以相機(jī)的世界單位來衡量的肛根。屏幕坐標(biāo)和相機(jī)之間滿足:Screen.width=Camera.pixelWidth和Screen.height=Camera.pixelHeight這兩個(gè)條件辫塌。例如我們將相機(jī)正對(duì)著場(chǎng)景中的原點(diǎn)(0,0,0),相機(jī)的Z軸分量為-10,按照屏幕坐標(biāo)的定義派哲,假設(shè)屏幕為800X640的大小臼氨,則此時(shí)原點(diǎn)轉(zhuǎn)化為屏幕坐標(biāo)后應(yīng)該是(400,320,10)。在Unity3D中我們可以使用WorldToScreenPoint來將一個(gè)世界坐標(biāo)轉(zhuǎn)換為屏幕坐標(biāo)芭届。

視口坐標(biāo)

視口坐標(biāo)是標(biāo)準(zhǔn)化后的屏幕坐標(biāo)储矩。標(biāo)準(zhǔn)化的概念我們可以引申到向量的標(biāo)準(zhǔn)化中,比如一個(gè)向量(x,y)將過標(biāo)準(zhǔn)化后可以得到一個(gè)單位向量(x’,y’)褂乍。類似地持隧,視口坐標(biāo)是以0到1間的數(shù)字來表示的,它的范圍是以左下角為(0,0),右上角為(1,1)定義的這樣一個(gè)矩形逃片。視口坐標(biāo)是一個(gè)3D坐標(biāo)屡拨,Z軸是以相機(jī)的世界單位來衡量的。通過對(duì)比可以發(fā)現(xiàn)視口坐標(biāo)和屏幕坐標(biāo)特別的相似,所以這里大家可以對(duì)比著來學(xué)習(xí)呀狼。同樣以屏幕坐標(biāo)中的例子來將這里的轉(zhuǎn)換裂允,例如我們將相機(jī)正對(duì)著場(chǎng)景中的原點(diǎn)(0,0,0),相機(jī)的Z軸分量為-10,按照屏幕坐標(biāo)的定義哥艇,假設(shè)屏幕為800X640的大小绝编,則此時(shí)原點(diǎn)轉(zhuǎn)化為屏幕坐標(biāo)后應(yīng)該是(0.5,0.5,10)。在Unity3D中我們可以使用WorldToViewportPoint來將一個(gè)世界坐標(biāo)轉(zhuǎn)換為視口坐標(biāo)貌踏。

GUI坐標(biāo)

GUI坐標(biāo)是指通過OnGUI方法繪制UI時(shí)使用的坐標(biāo)十饥。這個(gè)坐標(biāo)系和屏幕坐標(biāo)類似,它同樣是以像素來定義的哩俭,它的范圍是以左上角為(0,0),右下角為(Screen.width,Screen.height)定義的這樣一個(gè)矩形,GUI坐標(biāo)是一個(gè)[2D]坐標(biāo)(絕對(duì)坐標(biāo))拳恋。因?yàn)镚UI在早期的文章中曾有所設(shè)計(jì)凡资,屬于Unity3D中較為基礎(chǔ)的內(nèi)容,此外我們知道使用絕對(duì)坐標(biāo)來進(jìn)行布局的話是沒有辦法做自適應(yīng)的谬运,所以這部分內(nèi)容我們就不展開講了隙赁,UI自適應(yīng)的一個(gè)主要觀點(diǎn)就是不要使用絕對(duì)坐標(biāo)!不要使用絕對(duì)坐標(biāo)梆暖!不要使用絕對(duì)坐標(biāo)伞访!重要的事情要說三遍的嘛!這里想特別說說Unity4.6以后推出的全新UI支持:uGUI轰驳。在uGUI的Screen Space模式下厚掷,Unity3D的編輯器以屏幕坐標(biāo)來顯示UI元素的位置;在World Space模式下级解,Unity3D的編輯器以世界坐標(biāo)來顯示UI元素的位置冒黑。相信這一點(diǎn)大家在使用的時(shí)候都沒有注意到,最近在看一個(gè)論壇帖子的時(shí)候發(fā)現(xiàn)對(duì)uGUI坐標(biāo)轉(zhuǎn)換的相關(guān)知識(shí)一片茫然勤哗,所以對(duì)這部分內(nèi)容進(jìn)行了深入的研究抡爹,最終得出的結(jié)論是:uGUI的坐標(biāo)本質(zhì)上是特殊的屏幕坐標(biāo),因?yàn)閡GUI的Anchor決定了該坐標(biāo)系的原點(diǎn)芒划,pivot決定了元素本身坐標(biāo)系的原點(diǎn)冬竟,正是這兩個(gè)屬性讓uGUI的坐標(biāo)看起來顯得撲朔迷離。RectTransform組件繼承自Transform民逼,所以它們的position和localPosition是等價(jià)的泵殴,都是世界坐標(biāo);anchoredPosition是UI元素的屏幕坐標(biāo)拼苍,在對(duì)UI元素進(jìn)行操作的時(shí)候應(yīng)該考慮使用這個(gè)坐標(biāo)袋狞。

二、Unity3D各種坐標(biāo)系間的轉(zhuǎn)換

雖然Unity3D里提供了各種坐標(biāo)系間的轉(zhuǎn)換API,可是我們這是在寫博客不是在說API不是苟鸯?所以從實(shí)用性的角度出發(fā)同蜻,我們這里提供了一個(gè)Unity3D各種坐標(biāo)系間轉(zhuǎn)換的FAQ!

1、屏幕坐標(biāo)如何轉(zhuǎn)換為世界坐標(biāo)早处?

在Unity3D中通過camera.ScreenToWorldPoint(Vector3 v)方法可以將一個(gè)屏幕坐標(biāo)轉(zhuǎn)化為世界坐標(biāo)湾蔓。其中,camera是游戲場(chǎng)景中的場(chǎng)景相機(jī)砌梆。通過Input.mousePosition或者 Input.touches[0].position可以獲得鼠標(biāo)或者單根手指的屏幕坐標(biāo)默责。典型的應(yīng)用場(chǎng)景是第一人稱射擊游戲中子彈的發(fā)射和RPG游戲中點(diǎn)擊地面移動(dòng)角色

2、世界坐標(biāo)如何轉(zhuǎn)換為屏幕坐標(biāo)咸包?

在Unity3D中通過camera.WorldToScreenPoint(Vector3 v)方法可以將一個(gè)世界坐標(biāo)轉(zhuǎn)化為屏幕坐標(biāo)桃序。其中,camera是游戲場(chǎng)景中的UI相機(jī)烂瘫。比如我們需要將一個(gè)世界坐標(biāo)轉(zhuǎn)換到NGUI坐標(biāo)的時(shí)候媒熊,可以使用場(chǎng)景相機(jī)將世界坐標(biāo)轉(zhuǎn)為屏幕坐標(biāo),然后再利用UI相機(jī)將屏幕坐標(biāo)轉(zhuǎn)換為世界坐標(biāo)坟比,最后再賦值給NGUI控件芦鳍。典型的應(yīng)用場(chǎng)景是NPC頭頂?shù)奈淖诛@示和怪物頭頂?shù)难獥l顯示。

3葛账、屏幕坐標(biāo)如何轉(zhuǎn)換為視口坐標(biāo)柠衅?

在Unity3D中可以通過camera.ScreenToViewportPoint()來將一個(gè)屏幕坐標(biāo)轉(zhuǎn)換為視口坐標(biāo),其中camera是游戲場(chǎng)景中的場(chǎng)景相機(jī)籍琳。當(dāng)我們了解了視口坐標(biāo)本質(zhì)就是屏幕坐標(biāo)的標(biāo)準(zhǔn)化坐標(biāo)以后菲宴,這個(gè)真心沒有什么可說的趋急。

4裙顽、世界坐標(biāo)如何轉(zhuǎn)換為視口坐標(biāo)?

在Unity3D中可以通過camera.WorldToViewportPoint()來將一個(gè)世界坐標(biāo)轉(zhuǎn)換為視口坐標(biāo)宣谈,其中camera是游戲場(chǎng)景中的場(chǎng)景相機(jī)愈犹。當(dāng)我們了解了視口坐標(biāo)本質(zhì)就是屏幕坐標(biāo)的標(biāo)準(zhǔn)化坐標(biāo)以后,這個(gè)真心沒有什么可說的闻丑。

5漩怎、屏幕坐標(biāo)如何轉(zhuǎn)化為GUI坐標(biāo)?

我們注意到屏幕坐標(biāo)和GUI坐標(biāo)的根本差異在于坐標(biāo)系原點(diǎn)選定不同嗦嗡,即屏幕坐標(biāo)的原點(diǎn)在左下角勋锤,而GUI坐標(biāo)的原點(diǎn)在左下角。因此我們可以定義一個(gè)ScreenToGUIPoint方法:

private Vector2 ScreenToGUIPoint(Vector2 v)
{
return new Vector2(v.x,Screen.height-v.y)
}

6侥祭、GUI坐標(biāo)如何轉(zhuǎn)換為屏幕坐標(biāo)叁执?

一個(gè)更為神奇的事情是你可以繼續(xù)調(diào)用ScreenToGUIPoint方法茄厘。

7、屏幕坐標(biāo)如何轉(zhuǎn)換為uGUI坐標(biāo)谈宛?

當(dāng)我們接觸到uGUI以后常常會(huì)遇到類似NGUI需要為uGUI控件坐標(biāo)賦值的[問題]次哈,此時(shí)我們我們有以下兩種思路處理:直接把屏幕坐標(biāo)賦值給transform.position,這種方式簡(jiǎn)單粗暴在ScreenSpace-Overlay模式下沒有問題吆录,然而在ScreenSpace-Camera模式下會(huì)出現(xiàn)因?yàn)樯疃葦?shù)值不正確而引發(fā)的問題窑滞,需要注意(并且需要確保被賦值的物體在Canvas的根節(jié)點(diǎn)下),前段時(shí)間有人在群里問我position和localPosition的區(qū)別恢筝,我就呵呵噠哀卫,現(xiàn)在人都是一般的浮躁啊,寧肯整天鉆研某某插件的用法都不愿意鉆研下API文檔撬槽、計(jì)算機(jī)圖形學(xué)此改、3D數(shù)學(xué)這些東西。通過RectTransformUtility.ScreenPointToWorldPointInRectangle方法將屏幕坐標(biāo)轉(zhuǎn)化為世界坐標(biāo)然后再賦值給transform.position侄柔。兩種方法看起來大同小異共啃,然而這種方法是更為保險(xiǎn)的,因?yàn)樗谶@兩種模式下都能穩(wěn)定地運(yùn)行勋拟。更重要的是它可以和uGUI的事件系統(tǒng)完美地融合勋磕。我猜測(cè)它是直接改變UI元素的世界坐標(biāo)妈候,因?yàn)樗琴x值給transform.position敢靡。可是話說回來苦银,以前給怪物頭頂顯示血條的時(shí)候都是直接把世界坐標(biāo)轉(zhuǎn)屏幕坐標(biāo)再賦值給transform.position啸胧,這樣看來當(dāng)初的想法可能是錯(cuò)誤的呀,如果要給UI控件屏幕坐標(biāo)那不是應(yīng)該給anchoredPosition賦值嗎幔虏?好吧纺念,這塊兒暫時(shí)還沒有搞明白,如果有朋友知道怎么回事想括,可以告訴我陷谱,謝謝!

轉(zhuǎn)自

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末瑟蜈,一起剝皮案震驚了整個(gè)濱河市烟逊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌铺根,老刑警劉巖宪躯,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異位迂,居然都是意外死亡访雪,警方通過查閱死者的電腦和手機(jī)详瑞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來臣缀,“玉大人坝橡,你說我怎么就攤上這事「闻悖” “怎么了驳庭?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長氯窍。 經(jīng)常有香客問我饲常,道長,這世上最難降的妖魔是什么狼讨? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任贝淤,我火速辦了婚禮,結(jié)果婚禮上政供,老公的妹妹穿的比我還像新娘播聪。我一直安慰自己,他們只是感情好布隔,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布离陶。 她就那樣靜靜地躺著,像睡著了一般衅檀。 火紅的嫁衣襯著肌膚如雪招刨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天哀军,我揣著相機(jī)與錄音沉眶,去河邊找鬼。 笑死杉适,一個(gè)胖子當(dāng)著我的面吹牛谎倔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播猿推,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼片习,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了蹬叭?” 一聲冷哼從身側(cè)響起藕咏,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎具垫,沒想到半個(gè)月后侈离,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡筝蚕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年卦碾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了铺坞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡洲胖,死狀恐怖济榨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绿映,我是刑警寧澤擒滑,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站叉弦,受9級(jí)特大地震影響丐一,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜淹冰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一库车、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧樱拴,春花似錦柠衍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至正罢,卻和暖如春阵漏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背腺怯。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工袱饭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留川无,地道東北人呛占。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像懦趋,于是被迫代替她去往敵國和親晾虑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 無論是2d還是3d游戲開發(fā)仅叫,圖形學(xué)都是基礎(chǔ)帜篇,解析幾何的基本思想是將幾何圖形抽象成點(diǎn)的運(yùn)動(dòng)軌跡,從而點(diǎn)可以作為組成圖...
    tmgg閱讀 12,774評(píng)論 2 4
  • 3D坐標(biāo)系是在做3D項(xiàng)目開發(fā)中的基礎(chǔ)概念诫咱,一般來說3D軟件或者開發(fā)工具都是采用笛卡爾坐標(biāo)系來描述物體的坐標(biāo)信息笙隙。笛...
    S_H_C閱讀 6,230評(píng)論 0 6
  • 笛卡爾坐標(biāo)系的定義 :1、每個(gè)2D笛卡爾坐標(biāo)系都有一個(gè)特殊的點(diǎn)坎缭,稱為原點(diǎn)(0,0)它是坐標(biāo)系的中心竟痰。2签钩、每個(gè)2D笛...
    好怕怕閱讀 3,328評(píng)論 3 8
  • 一、 World Space(世界坐標(biāo)) 我們?cè)趫?chǎng)景中添加物體(如:Cube)坏快,他們都是以世界坐標(biāo)顯示在場(chǎng)景中的铅檩。...
    HoyaWhite閱讀 2,521評(píng)論 0 0
  • Unity3D的四種坐標(biāo)系 【Unity3D的四種坐標(biāo)系】 1、World Space(世界坐標(biāo)):我們?cè)趫?chǎng)景中添...
    Babybus_Unity閱讀 1,169評(píng)論 0 1