本帖最后由 RaymondChan 于 2018-2-6 21:15 編輯 注:本文屬于基礎(chǔ)系列,高手可以略過哦 1. 寫在前面 你有沒有過類似這樣子的疑惑? 1.明明我只拖動(dòng)了一個(gè)物體z軸,為何檢視面板上其余兩個(gè)軸的值也發(fā)生變化了?檢視面板上顯示的不就是本地坐標(biāo)嘛,總不會(huì)是世界坐標(biāo)?那也不對呀! 2.使用transform.localPosition移動(dòng)一個(gè)物體,我們只是想讓一個(gè)物體往它的z軸方向移動(dòng),為何實(shí)際運(yùn)行時(shí)卻不是,而是不知道往哪個(gè)方向移動(dòng)了,這是什么鬼? 如果你已經(jīng)想明白這些疑惑,那么請?jiān)O(shè)想以下情形: 新建一個(gè)Cube,將其Rotation的Y值改為300,為其添加腳本,在Update中分別執(zhí)行以下語句時(shí),先想一想各自會(huì)怎么移動(dòng)?然后對比一下后面的結(jié)果(可以注意下上方的Global與Local的切換)。如果你依然有疑惑,我覺得咱們可以繼續(xù)往下看。
實(shí)際結(jié)果如下: 1 transform.Translate(Vector3.forward * Time.deltaTime); ![]() 2 transform.Translate(transform.forward * Time.deltaTime); ![]() 3 transform.position += Vector3.forward * Time.deltaTime; ![]() 4 transform.localPosition += Vector3.forward * Time.deltaTime; ![]() 5 transform.position += transform.forward * Time.deltaTime; ![]() 6 transform.localPosition += transform.forward * Time.deltaTime; ![]() 7 Vector3 objVector3=transform.InverseTransformDirection(Vector3.forward); transform.Translate(objVector3*Time.deltaTime); ![]() 2. Unity坐標(biāo)系基礎(chǔ) 如果對上面的內(nèi)容有疑惑,我們可能先需要重新了解一下Unity的坐標(biāo)系。在Unity中常用的坐標(biāo)系有全局坐標(biāo)系、局部坐標(biāo)系、相機(jī)坐標(biāo)系、屏幕坐標(biāo)系,我們今天主要涉及的是全局坐標(biāo)系與局部坐標(biāo)系。 全局坐標(biāo)系 全局坐標(biāo)系是用來描述游戲場景內(nèi)所有物體位置和方向的基準(zhǔn),我們一般也叫它世界坐標(biāo)系。在Unity場景中創(chuàng)建的物體都是以全局坐標(biāo)系中的坐標(biāo)原點(diǎn)來確定各自位置的。所以,全局坐標(biāo)系是基準(zhǔn),我們可以使用世界坐標(biāo)來保存一個(gè)物體的確切位置。 局部坐標(biāo)系 每個(gè)物體都有其獨(dú)立的物體坐標(biāo)系,并且隨物體進(jìn)行相同的移動(dòng)或者旋轉(zhuǎn),也可以叫做模型坐標(biāo)系或物體坐標(biāo)系。模型Mesh保存的頂點(diǎn)坐標(biāo)均為局部坐標(biāo)系下的坐標(biāo)。Unity工具欄上的Global/Local按鈕可以切換顯示全局坐標(biāo)系和局部坐標(biāo)系。這里要注意了,當(dāng)切換到Local的時(shí)候,顯示的是物體自身的坐標(biāo)系,是自身的坐標(biāo)系,是自身的坐標(biāo)系,是自身的坐標(biāo)系,重要的事多說幾遍。 3. Transform中容易混淆的幾個(gè)問題 transform.position與transform.localPostion(rotation同理) transform.position 是物體的世界坐標(biāo),也就是相對世界坐標(biāo)系原點(diǎn)的位置; transform.localPosition 這個(gè)大家一般理解為本地坐標(biāo),而一般問題也就出在“本地”這兩個(gè)字的理解上,這個(gè)“本地”不是物體的自身的坐標(biāo)系(這個(gè)local不是工具欄上Global/Local中的Local),而是指父物體的坐標(biāo)系,當(dāng)沒有父物體時(shí),就是世界坐標(biāo)系,換句話說如果這個(gè)物體有父物體,那么localPosition就是該物體的相對父物體的自身坐標(biāo)系原點(diǎn)的位置,如果沒有父物體,那么localPosition就會(huì)等于position。 給大家畫個(gè)圖方便大家理解一下。為了便于觀察,我們使用二維坐標(biāo)系來演示,如下圖,A物體的position為(2,3),B物體的position為(5,4),如果A物體是B物體的父物體,那么B物體的localPosition就是以A點(diǎn)為原點(diǎn)的相對坐標(biāo)(5-2,4-3)即(3,1) ![]() vector3.forward與transform.forward(up、right同理) vector3.forward 這個(gè)值大家看到forward很容易將它與世界坐標(biāo)聯(lián)系起來,但它就只是一個(gè)三維向量,forward只是一個(gè)記法而已,官方表述是shorthand,它的值永遠(yuǎn)都是(0, 0, 1),與世界坐標(biāo)沒有任何關(guān)系,你將它用在世界坐標(biāo)(position)里,它就代表著世界坐標(biāo)的(0,0,1),你將它用在本地坐標(biāo)上(localPosition),那么它就代表著本地坐標(biāo)中的(0,0,1),這一點(diǎn)要記住,否則很容易搞錯(cuò); transform.forward 這也是一個(gè)三維向量,方向是該物體的自身坐標(biāo)系的z軸方向,長度是世界坐標(biāo)系中的1,由于這個(gè)向量的方向是該物體自身z軸方向,所以這個(gè)三維向量的值是會(huì)變化的,是基于世界坐標(biāo)系計(jì)算得到的值。 Transform在檢視面板上的顯示的值 ![]() 這里的Position是localPosition的值,是在父物體的坐標(biāo)系下的值,也就是相對父物體原點(diǎn)的位置。這與工具欄上的Local是不一樣的。所以才會(huì)出現(xiàn)直接拖拽物體的z軸,而檢視面板中不一定是z的值在變化。 Translate是指定坐標(biāo)系的 public void Translate(Vector3 translation, Space relativeTo = Space.Self); public void Translate(Vector3 translation, Transform relativeTo); Translate方法具有多個(gè)重載方法,當(dāng)我們不指定坐標(biāo)系時(shí),默認(rèn)是按自身坐標(biāo)系進(jìn)行位移,我們也可以指定為世界坐標(biāo)系,當(dāng)然也可以指定為其他任意物體自身的坐標(biāo)系。所以當(dāng)我們使用默認(rèn)坐標(biāo)系時(shí),要記住這是物體自身的坐標(biāo)系。 4. 對1中7種移動(dòng)的分析
5. 再次思考 我們加點(diǎn)改變,在上述的Cube下新建一個(gè)子物體cube,與父物體拉開一段距離,進(jìn)行一點(diǎn)任意旋轉(zhuǎn),只對子物體同樣執(zhí)行以上語句,子物體cube都會(huì)怎么移動(dòng)? 這里我就不再贅述啦,大家可以自己嘗試哦。如果這個(gè)依然可以想明白,那么到這里基本上就OK啦。 ![]() 6. 小結(jié) 帶著大家回顧了下Unity中的全局坐標(biāo)系與局部坐標(biāo)系,分析了幾種容易混淆的問題以及幾種移動(dòng)的方式,希望可以給大家?guī)硪稽c(diǎn)幫助。 工程文件(Unity 2017.3.0f3): 鏈接:https://pan.baidu.com/s/1bqiT9FL 密碼:xd11 |
|