国产精品天干天干,亚洲毛片在线,日韩gay小鲜肉啪啪18禁,女同Gay自慰喷水

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Unity簡(jiǎn)單的2D物理系統(tǒng)的實(shí)現(xiàn)

2023-05-28 22:36 作者:兔子愛好者  | 我要投稿

遇見的問題

在使用unity創(chuàng)建2D項(xiàng)目的時(shí)候,雖然unity自己提供了例如Rigidbody2D與Collider2D等組件來提供對(duì)2D項(xiàng)目的支持.但unity的本質(zhì)依然是一個(gè)3D引擎,這里提供的2D的組件依然是基于3D引擎,無法對(duì)真正的2D項(xiàng)目提供很好的支持.

解決的辦法

unity的2D組件在為2D Platform類型的項(xiàng)目提供支持的時(shí)候,只能說功能堪堪可以使用,但是依然有很大的需要改變的地方. 比較好的辦法是自己來創(chuàng)建一個(gè)滿足2D項(xiàng)目需求的物理系統(tǒng).

一部分效果展示

性能與功能對(duì)比

在場(chǎng)景內(nèi)放置1000個(gè)僅攜帶BoxCollider2D(不含剛體)的會(huì)移動(dòng)的物體(攜帶自制的動(dòng)畫控制器與AI),此時(shí)的幀數(shù)僅有6幀.


在場(chǎng)景內(nèi)放置10000個(gè)不攜帶unity提供的碰撞體的會(huì)移動(dòng)物體,此時(shí)幀數(shù)尚且能保持15幀左右


在場(chǎng)景內(nèi)發(fā)射1100發(fā)速度固定,并且未碰撞時(shí)生命時(shí)常無限的攜帶BoxCollider2D與Kinematic類型的Rigidbody2D子彈,此時(shí)的幀數(shù)也僅有個(gè)位數(shù)的了.

在上一圖中,如果去掉剛體,此時(shí)發(fā)射1100發(fā)子彈幀數(shù)依然有100幀左右.

此時(shí)繼續(xù)追加子彈,當(dāng)子彈數(shù)目追加刀1500發(fā)時(shí),幀數(shù)僅剩個(gè)位數(shù).

如果在去掉BoxCollider2D并開啟自制物理系統(tǒng)的碰撞檢測(cè),放置5個(gè)允許子彈碰撞的運(yùn)動(dòng)物體(即每發(fā)子彈每幀需要與5個(gè)物體做碰撞檢測(cè),這個(gè)數(shù)目不包含墻壁等),此時(shí)將子彈增加到1萬發(fā)以上,依然能有很高的幀數(shù)

繼續(xù)將子彈追加刀2萬發(fā),效果如下圖

最終追加到3萬發(fā)子彈,幀數(shù)仍然有20幀以上


其他說明:這些物體允許與平臺(tái)(包括地面墻壁頂部與單向板子)碰撞并且禁止同行(或允許單向通行).

這些物體也允許被玩家碰撞,對(duì)玩家造成傷害(如果取消怪物對(duì)玩家的碰撞效果,改為攻擊行為才造成傷害,性能也會(huì)更好).

這些物體也允許被子彈碰撞,允許觸發(fā)子彈造成的傷害或者效果.

目前物體(包括玩家或者怪物)與平臺(tái)的碰撞使用射線實(shí)現(xiàn),在使用中遇見了挺多的麻煩,性能也相比之下不如自制的物理系統(tǒng).目前已有解決方案,預(yù)計(jì)會(huì)在下一個(gè)版本完全由自制物理系統(tǒng)實(shí)現(xiàn).

單向通行板

允許玩家(或者敵人,或者指定敵人)單向通行(包括跳躍)

無碰撞體與剛體的玩家與無碰撞體與剛體的敵人或者道具碰撞

允許玩家與其他不包含碰撞體或者剛體的物體互相碰撞并且觸發(fā)碰撞事件

方形碰撞器/圓形碰撞器相互碰撞的實(shí)現(xiàn)

方形碰撞器(A)與其他碰撞器(B)的碰撞檢測(cè)

取A的四個(gè)頂點(diǎn),只要任意頂點(diǎn)落入B的范圍之內(nèi),則判定為發(fā)生碰撞

圓形碰撞器(A)與方形碰撞器(B)的碰撞檢測(cè)

取B的四個(gè)頂點(diǎn),只要任意頂點(diǎn)落入A的范圍之內(nèi),則判定為發(fā)生碰撞

圓形碰撞器(A)與圓形碰撞器(B)的碰撞檢測(cè)

計(jì)算AB的圓心距即可

簡(jiǎn)易優(yōu)化

計(jì)算方形碰撞器的時(shí)候,根據(jù)物體位于的相對(duì)方位(上下左右)優(yōu)先計(jì)算左上和右下或者右上和左下兩個(gè)頂點(diǎn),可以更少的計(jì)算就能獲得結(jié)果.

動(dòng)態(tài)碰撞體A與動(dòng)態(tài)碰撞體B的X或者Y的距離大于一定值,則一定不相撞,省略后面的計(jì)算.

動(dòng)態(tài)碰撞體A與動(dòng)態(tài)碰撞體B的X或者Y的距離大于一定值,根據(jù)這個(gè)值計(jì)算兩個(gè)物體最短M幀后才會(huì)碰撞,在此期間將B移除與A的碰撞檢測(cè),在M幀之后放回.

動(dòng)態(tài)碰撞體A與純粹類靜態(tài)碰撞體B(如墻壁),同一時(shí)間一定只能有A與一個(gè)B相撞(完成純粹類靜態(tài)碰撞體融合之后),此時(shí)只用計(jì)算A在情況時(shí)候脫離B即可.

注:三角形碰撞器下個(gè)版本實(shí)現(xiàn)

純粹類靜態(tài)碰撞體(墻壁與靜態(tài)觸發(fā)點(diǎn)等)目前的難點(diǎn)

由于動(dòng)態(tài)碰撞體和道具類靜態(tài)碰撞體都是一個(gè)固定類型(大小與頂點(diǎn)等),創(chuàng)建的同類的物體碰撞體都是固定的參數(shù).

但是純粹類靜態(tài)碰撞體,本身的大小與頂點(diǎn)等參數(shù)可能每一個(gè)都不同,每單獨(dú)一個(gè)碰撞體就歸于一類實(shí)在是工作量比較大.

解決方案1

制作固定可重用的Tile,并且相鄰的Tile會(huì)融合形成一個(gè)整體,提高碰撞檢測(cè)效率.但是可能得做一部分unity editor的開發(fā),然后就是每一種瓦片就得花費(fèi)一些時(shí)間制作一下.最后則是繪制好的地圖需要做序列化然后存儲(chǔ),在游戲運(yùn)行的時(shí)候來反序列化,然后生成關(guān)卡,在關(guān)卡生成的時(shí)候會(huì)自動(dòng)完成碰撞體的注冊(cè).

解決方案2

依然使用GameObject,會(huì)為該對(duì)象附加一個(gè)碰撞體組件與一個(gè)Mono Behavior組件,這個(gè)組件會(huì)自動(dòng)獲取該對(duì)象的碰撞體,并且計(jì)算大小與頂點(diǎn)后注冊(cè)在自制物理系統(tǒng)中.

一旦注冊(cè)完成則自動(dòng)銷毀該碰撞體與腳本. 這個(gè)方案的缺點(diǎn)是沒法完成覆蓋的碰撞體的融合與拆分,如果地圖設(shè)計(jì)不合適,會(huì)提高一部分資源消耗.

非剛體移動(dòng)的問題與解決方案

角色嵌入墻體的問題

由于在我的自制物理系統(tǒng)中完全拋棄的剛體,那么所有的移動(dòng)都是瞬移(Translate)來完成的,如果角色速度過大,可能導(dǎo)致角色陷入墻體.

為什么會(huì)發(fā)生這個(gè)情況?

假設(shè)當(dāng)前是第A幀,此時(shí)角色的速度為V,正面的墻壁與角色的距離為D,且有D<V,并且D>0.

在上面的場(chǎng)景中,當(dāng)前幀角色沒有與墻壁相撞,這意味著角色當(dāng)前幀可以向當(dāng)前方向移動(dòng).如果移動(dòng)完成,此時(shí)角色與墻壁的距離為D-V=R.根據(jù)條件可知R<0,此時(shí)角色就已經(jīng)嵌入墻壁中了.

如何解決

將角色與墻壁碰撞檢測(cè)距離延長(zhǎng)為當(dāng)前速度V,當(dāng)檢測(cè)到角色與墻壁發(fā)生碰撞的時(shí)候,此時(shí)角色與墻壁的距離D必然有D<V且D>=0,那么當(dāng)前幀使V=D,下一幀到來時(shí)角色最大位移D的距離,此時(shí)角色與墻壁的距離為0,角色與墻壁相撞,當(dāng)前幀我們不在允許角色繼續(xù)向該方向移動(dòng).

斜坡移動(dòng)的問題

即使unity自身也沒有提供2D項(xiàng)目的斜坡移動(dòng)方案,這個(gè)問題當(dāng)然只能自己解決了.

在下面的例子中,我們假設(shè)角色向右移動(dòng),且使用了方形碰撞器,并且角色的移動(dòng)能夠越過高度為Y的坎或者坡度小于arctan(Y/V)的坡

如何正確的斜坡移動(dòng)(向上)

取角色右上(P1)與右下(P2)兩個(gè)頂點(diǎn),向右檢測(cè)D的距離(可以額外用一幀讓玩家完全靠近后在做接下來的操作),如果P1檢測(cè)成功但是P2檢測(cè)失敗,則說明玩家向右移動(dòng)遇見了斜坡(或者坎).

此時(shí)我們聲明一個(gè)新的點(diǎn)P3,這個(gè)點(diǎn)與P2點(diǎn)在X軸距離V個(gè)單位,在Y軸距離Y個(gè)單位.

之后由P3點(diǎn)向下檢測(cè),假設(shè)P3與斜坡(坎)的距離為M.如果M<=0,則說明坡度過大或者坎過高,因?yàn)檫@次位移會(huì)導(dǎo)致玩家進(jìn)入墻體,因此禁止位移.如果M>0,則說明玩家的該次位移沒有問題.此時(shí)玩家的位移向量為(X,Y-M)

如何正確的斜坡移動(dòng)(向下)

實(shí)際上,如果你之前物理系統(tǒng)檢測(cè)玩家是否在地板上的代碼沒有問題的話,此時(shí)玩家的角色就會(huì)正確的自動(dòng)向下移動(dòng)才對(duì).

但是如果每次一旦檢測(cè)到玩家踏空,就調(diào)用TransientToFloating()完成狀態(tài)轉(zhuǎn)化的話,這里確實(shí)會(huì)出問題.每一幀的移動(dòng)都會(huì)導(dǎo)致玩家轉(zhuǎn)換到浮空狀態(tài)然后復(fù)原站立/奔跑狀態(tài)(這會(huì)導(dǎo)致動(dòng)畫轉(zhuǎn)換鬼畜),在不恰當(dāng)?shù)膱?chǎng)合玩家會(huì)做出多次狀態(tài)轉(zhuǎn)化. 這意味著也許需要專門針對(duì)斜坡向下的移動(dòng)來完成指定的功能. 這部分問題預(yù)計(jì)下一個(gè)版本解決.


Unity簡(jiǎn)單的2D物理系統(tǒng)的實(shí)現(xiàn)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
鄂州市| 银川市| 宣武区| 巴青县| 隆回县| 手游| 冕宁县| 定西市| 寿宁县| 彩票| 阿荣旗| 漯河市| 大埔区| 麻阳| 四川省| 上蔡县| 垣曲县| 泾川县| 武威市| 深圳市| 墨竹工卡县| 辰溪县| 甘南县| 温泉县| 松桃| 伊川县| 独山县| 耿马| 禹城市| 铜川市| 治多县| 山西省| 富宁县| 香港 | 湘乡市| 永福县| 闽清县| 沐川县| 甘肃省| 沧源| 旺苍县|