博客對(duì)Unity內(nèi)坐標(biāo)系的轉(zhuǎn)換和API進(jìn)行一個(gè)總結(jié)和原理推測(cè)解析
Unity內(nèi)的坐標(biāo)系組成
世界坐標(biāo)
將游戲內(nèi)的游戲空間理解為"世界"曙聂,世界坐標(biāo)系對(duì)等于游戲空間坐標(biāo)系偿枕,游戲中的transform.position或者transform.rotation的信息都是基于世界坐標(biāo)系
視圖坐標(biāo)
視圖坐標(biāo)是對(duì)游戲顯示視圖的一個(gè)歸一化的描述,其中左下角為(0栈暇,0)麻裁,右上角為(0,1)源祈,在需要對(duì)顯示視圖進(jìn)行分屏處理時(shí)煎源,可以通過(guò)設(shè)置Camera上的ViewPort Rect屬性來(lái)進(jìn)行屏幕分屏渲染
屏幕坐標(biāo)
屏幕坐標(biāo)是對(duì)屏幕像素(分辨率)的位置的描述,其中左下角為(0香缺,0)手销,右上角為(Screen.width,Screen.height),比如游戲分辨率為1280*720赫悄,則Screen.width=1280,Screen.height=720原献。
觀察坐標(biāo)
?Unity中的游戲畫面始終由攝像機(jī)來(lái)提供,觀察坐標(biāo)是已渲染該游戲體的攝像機(jī)坐標(biāo)為原點(diǎn)的相對(duì)坐標(biāo)埂淮。
Unity提供的坐標(biāo)轉(zhuǎn)換API
//1.屏幕轉(zhuǎn)世界坐標(biāo)
Camera.main.ScreenToWorldPoint();
姑隅!需要注意的是屏幕轉(zhuǎn)世界坐標(biāo)的時(shí)候要注意坐標(biāo)的z值,z值為目標(biāo)與相機(jī)的z軸差值
//2.世界轉(zhuǎn)屏幕坐標(biāo)
Camera.main.WorldToScreenPoint();
//3.世界轉(zhuǎn)視口坐標(biāo)
Camera.main.WorldToViewportPoint();
//4.視口轉(zhuǎn)世界坐標(biāo)
Camera.main.ViewportToWorldPoint();
//5.視口轉(zhuǎn)屏幕坐標(biāo)
Camera.main.ViewportToScreenPoint();
//6.屏幕轉(zhuǎn)視口坐標(biāo)
Camera.main.ScreenToViewportPoint();
原理推測(cè)解析
反匯編后發(fā)現(xiàn)引用的是c++代碼倔撞,對(duì)實(shí)現(xiàn)原理只做推測(cè)和解析
世界坐標(biāo)與屏幕坐標(biāo)的相互轉(zhuǎn)換
我們知道游戲內(nèi)的相機(jī)是一個(gè)棱錐的觀察空間讲仰,計(jì)算屏幕坐標(biāo)的時(shí)候,根據(jù)游戲體和攝像機(jī)的z值差與攝像機(jī)的視角角度(Field of View)通過(guò)三角函數(shù)獲取到棱錐在該深度的錐形底面寬和高痪蝇,根據(jù)游戲體的x鄙陡,y坐標(biāo)與當(dāng)前地面寬高比例計(jì)算當(dāng)前分辨率下的屏幕坐標(biāo)
一個(gè)簡(jiǎn)單的例子小球的坐標(biāo)為(0,5,15)冕房,攝像機(jī)坐標(biāo)為(0,0,0),當(dāng)前屏幕分辨率為1280*720
計(jì)算屏幕坐標(biāo)Y值為:tan30°乘以z差值15趁矾,得到當(dāng)前深度的錐形成像空間一半的寬度為5√3 耙册,由于坐標(biāo)系從正中心開(kāi)始,Y軸坐標(biāo)5毫捣,計(jì)算映射比例為 ((5+5√3)?10√3)*720=567.8详拙,以下是API返回的屏幕坐標(biāo)證明計(jì)算過(guò)程是正確的
世界坐標(biāo)與視口坐標(biāo)的相互轉(zhuǎn)換
看懂世界坐標(biāo)轉(zhuǎn)屏幕坐標(biāo)的原理后自然就明白了世界坐標(biāo)轉(zhuǎn)視口坐標(biāo)的原理,只計(jì)算比例后就是屏幕坐標(biāo)
屏幕坐標(biāo)與視口坐標(biāo)的相互轉(zhuǎn)換
很簡(jiǎn)單蔓同,直接計(jì)算與分辨率的比例即可