ETH官方钱包

前往
大廳
主題

【Unity 工具製作筆記】 做個(gè) 自動(dòng)找路腳本

%%鼠 拒收病婿 | 2021-01-01 19:15:00 | 巴幣 32 | 人氣 848

一些測(cè)試成果圖 (找出球體到圓柱體的路徑):




還有可以跳的設(shè)定 (球體上面藍(lán)色線代表球最高跳躍高度,所以它可以跳過(guò)牆壁)



以下是製作心得與筆記:


腳本最主要的方法就是 int FindPath(int count, Vector3 start, Vector3 previous, List<MovePoint> result)
原理是遞迴找到可到達(dá)的路徑,回傳0,或用光步數(shù)回傳-1代表失敗。

遞迴是種不斷call自己的方法,在方法跑到底之前不斷呼叫自己,造成佔(zhàn)據(jù)一堆記憶體。
我這個(gè)做法最容易讓程式當(dāng)?shù)舻牡胤绞怯胹plit()方法分出太多路線,導(dǎo)致每個(gè)路線都要跑到結(jié)果才能釋放該路線的記憶體,在沒(méi)有優(yōu)化的狀況下找路都可能跑個(gè)5分鐘以上。

邏輯:
每隔一段固定距離向目標(biāo)點(diǎn)射出一個(gè)ray,若該ray沒(méi)打到障礙物,則可直行至該ray的盡頭。
→若打到物體,則判斷該障礙物是否可以跳過(guò):

CheckCanJump()又分成判斷往上跳還是往下跳(跳下高臺(tái)),
用畢氏定理射條剛好長(zhǎng)度再多一點(diǎn)點(diǎn)的ray至牆壁,(不知道為甚麼高好長(zhǎng)度的ray會(huì)偵測(cè)不到),看牆壁是否有高過(guò)這個(gè)ray的末端,被註解的Physics.CheckSphere作法也可以用。

→若是不可跨越的障礙物則沿著障礙物表面左右分裂出2條路線。
一開(kāi)始先判斷 (hit.normal != previous_split_normal) 是減少split次數(shù)的做法,若這次打到的表面的法線方向與上一次分裂的相同,代表無(wú)須再分裂,繼續(xù)沿著目前的方向前行就好。

MovePoint型態(tài)目前只是簡(jiǎn)單的紀(jì)錄位置,之後會(huì)多些狀態(tài)告訴移動(dòng)的物件走到這個(gè)點(diǎn)該做的動(dòng)作(?

Split方法:
第294~297行是將hit normal轉(zhuǎn)90度與-90度:
旋轉(zhuǎn)一個(gè)vector 90度的做法參考這篇
再乘個(gè)負(fù)號(hào)就變成-90度了。

第298、299的做法也可以,GetRotated_Pos()單純是:
return Quaternion.Euler(0, angle, 0) * (currentPos - center) + center;

檢查兩條分裂的路線有沒(méi)有與來(lái)的路線相交,有相交的話就可以刪掉。
檢查作法:
當(dāng)初在做分離軸碰撞判斷時(shí),大量用到線段相交判斷:(影片的腳本可以看myCollider core)

原理是分別將碰撞器A與碰撞器B的所有頂點(diǎn)投影在碰撞器A、B所有線段的法線上,比較該碰撞器A、B投影下最大與最小點(diǎn),看是否交叉。
不過(guò)以上作法是因?yàn)榕鲎财鰽和B是多邊形,所以要loop過(guò)所有頂點(diǎn)與線段,目前這個(gè)腳本只用到線段比較。


(因?yàn)樘珣械卯?huà)示意圖,就直接用whiteboarding時(shí)的圖吧)
要用其中一條線當(dāng)投影軸的原因是:
若投影軸單純用vector.up與vector.right,則下面這個(gè)情況會(huì)被當(dāng)成有相交,但實(shí)際上並沒(méi)有。

將投影軸改以其中一條線為基準(zhǔn):(紅色箭頭代表v2線段的normal)

做這麼多就只是為了盡量減少split()分裂出線段

說(shuō)到底這個(gè)腳本只是一堆if else的聚合物吧
更複雜的地形有可能找不到路,或是吃了一堆記憶體與種種效能問(wèn)題。
也許像Unity內(nèi)建的navigation先掃描地形的做法比較好,但之前用unity navigation時(shí)物件會(huì)奇怪的漂移,明明沒(méi)在走卻一直往某個(gè)地方飄移過(guò)去。 所以這次大膽做個(gè)尋路工具,不知道各位想法如何


雜記:
whiteboarding的過(guò)程




雜記2:
我思考就會(huì)拉肚子,尤其是打程式的時(shí)候
今天只喝了一杯咖啡、一杯牛奶和一條巧克力能量棒,在打這個(gè)腳本的期間拉了4次肚子,好奇測(cè)一下發(fā)現(xiàn)體重直接流掉半公斤,太棒了吧(?
送禮物贊助創(chuàng)作者 !
0
留言

創(chuàng)作回應(yīng)

KK
乳糖不適癥?腸胃不是不爭(zhēng)氣,偶爾也需要休息
2021-01-01 19:28:17
%%鼠 拒收病婿
聽(tīng)說(shuō)比較像是腸躁癥,最高紀(jì)錄是有次我什麼都沒(méi)吃卻壞肚子6次
2021-01-01 20:35:34
樂(lè)小呈
is樂(lè)小呈 遞迴用在這裡不太好吧,這樣要把每條路都走過(guò)一次誒?
navigation用的是A*算法,可以參考一下
2021-01-01 19:32:20
%%鼠 拒收病婿
感謝! 我來(lái)看看
2021-01-01 20:35:48
%%鼠 拒收病婿
突然想到,有辦法知道障礙物是可跨過(guò)的物件嗎?
2021-01-01 20:45:57
御安鴨·摸頭害鴨哭
2021-01-01 20:12:19
%%鼠 拒收病婿
感謝提供 重慶那個(gè)公路看起來(lái)有夠可怕
2021-01-01 20:36:23
頑皮大野狼
咖啡蠻傷腸胃的,如果累就睡覺(jué)跟走路散步運(yùn)動(dòng)提神,真的需要衝刺才喝
2024-03-26 23:05:12
追蹤 創(chuàng)作集

作者相關(guān)創(chuàng)作

更多創(chuàng)作