Unity自定义角色控制器(一):碰撞检测
我實在很喜歡用Unity。它在處理很多底層問題的同時有給了開發(fā)者很多自由。而且它還有著非常活躍的社區(qū),起到了很大的幫助。
不幸的是,之前也說了,Unity也帶著世界上最糟糕的角色控制器。在與Unity對比之前,這里我闡明一下廣義上的角色控制器是什么。其實角色控制器無非就是處理角色與游戲世界碰撞的一堆代碼。它不像箱子、柵欄之類的可以有物理引擎統(tǒng)一處理,角色行為上的特殊性需要代碼特殊處理。由于我們需要做碰撞檢測,我們還是需要選擇一個幾何形體去表示我們的角色。大多數(shù)3D游戲都會選擇膠囊體。
?
膠囊體的廣泛使用有著很多原因,具體原因我們有機會再討論。現(xiàn)在,為了讓問題簡單,我們先看看二維情況下的角色控制器。
?
你會看到我已經(jīng)把坐標標記為z軸和y軸,而不是x軸和y軸。這是因為我將會從頂視圖來觀察這個三維世界。由于頂視圖的緣故,那個藍色圓形是膠囊體。綠色矩形是一堵墻。理想的狀況是,角色無法穿過墻壁。因此當(dāng)角色與墻體交叉時,我希望能夠檢測出碰撞的發(fā)生,然后正確地進行處理。之所以我們自己處理碰撞檢測,也就是看看圓形是否與矩形發(fā)生了交叉,有兩個原因。一個是Unity有相當(dāng)多的資源(我們后面會講)來處理這個問題,第二個就是這是一個講解碰撞檢測的好例子。我們將會讓碰撞體計算出正確的位置從而得到合理的行為。
?
上面展示了我們的角色嘗試去朝著墻面運動。為了處理這個問題,我們從角色位移的起點與位移的終點之間進行一次掃略體測試。這次測試的結(jié)果是有一面墻在我們的前方,并且返回到墻面的距離。那么我們就可以直接拿到這個距離,將角色按照方向移動所得碰撞距離,從而移動到墻體之前。(PS:Unity有著很多內(nèi)建的功能可以做到這點,包括Rigidbody.SweepTest,Physics.SphereCast,Physics.CapsuleCast)。
但是,這并不完全是我們想要的效果。如果我們用了這種方法,角色在與物體稍稍碰撞之后,就再也沒有進行任何移動了。問題在于它缺少了現(xiàn)實中的反彈與側(cè)滑。
?
這個效果就更加合理一些。最初的掃略測試是在移動方向上進行的。當(dāng)掃略測試接觸到墻體之后,角色就直接移動過去,就像剛才那樣。但是這次我們更進一步,讓角色向上滑動來補足丟失的移動,這樣使得可以沿著表面滑動。這是一個理想中的角色控制器該有的行為,但這不是實現(xiàn)它的最佳方法。首先,這么做效率不是很高:手機靚號拍賣每次你想移動角色,你就需要執(zhí)行這個函數(shù)。如果每幀只執(zhí)行一次還好,但是假如因為某些原因這個函數(shù)要執(zhí)行多次,那就消耗很大。其次,碰撞處理是依賴于角色移動的方向和距離。如果角色因為某種神奇的原因進入了墻體內(nèi)部,角色是不會被推出的。實際上,我發(fā)現(xiàn)這個問題很讓人頭疼。
這是一個糟糕的情況。我們可以看到我們的英雄現(xiàn)在已經(jīng)在墻體內(nèi)部了。這種情況下,我們不應(yīng)該再考慮怎么像之前一樣處理碰撞,而是當(dāng)做一種獨立的情況來處理。我們不再關(guān)心玩家朝哪個方向移動或者移動了多遠。而是我們應(yīng)該考慮的是,這一刻他應(yīng)該在哪個位置,這個位置是否存在問題。在上圖中,我們可以看到玩家正在與墻體交叉(在墻體內(nèi)部了),因此他當(dāng)前位置存在問題,并且需要修正。自從我們不再將處理碰撞檢測作為運動的反饋,我們是不知道之前的位置在哪或者移動了多遠。而我們所知道的是,他目前卡在墻內(nèi),而我們需要將他從墻體內(nèi)挪出來。但是應(yīng)該挪到哪里呢?就像之前的例子一樣,我們應(yīng)該在剛接觸墻面的時候就將其推出。這里我們有不少候選位置。
?
每個半透明黃色圓圈都指示了一個潛在的滿足推出的位置。但是我們應(yīng)該選擇哪個呢?很簡單,只要選擇距離角色最近的墻面的最近點即可。
?
這里我們計算得出距離角色最近點位于右邊。接著我們就可以將角色移動到該點,加上角色的半徑(紅色部分)。
到這里就結(jié)束了我們深入神秘的角色控制器的第一部分。下次,我將會開始談?wù)勅绾卧赨nity中實現(xiàn),以及一些角色控制器會用到的更加復(fù)雜的函數(shù)。
致謝與引用:
這里的大多數(shù)知識都來源于兩個信息源:Unity論壇上的用戶techmage以及逆向分析Unity角色控制器包的用戶fholm。兩個名字都不知道怎么發(fā)音。不管怎樣,在RPGController目錄下。這是一個很不錯的項目,代碼寫得很好。很顯然,他時做Unity顧問的,如果有誰需要這個服務(wù)的話。最后,如果誰有關(guān)于這個話題的很好的資源,不妨與我分享一下。
總結(jié)
以上是生活随笔為你收集整理的Unity自定义角色控制器(一):碰撞检测的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何“漂亮”地解决dota类游戏网络延迟
- 下一篇: 如何用Unity和Cardboard做一