書中提到的群聚行為其實很單純且基本
來自於1987年SIGGRAPH論文,由Craig Reynolds發表的
『 Flocks, Herds, and Schools: A Distributed Behavioral Model 』
其行為主要是模擬鳥類及魚群的移動方式
基本原理一共有三點:
1. 凝聚(Cohesion):每個AI都會往鄰近AI的平均位置移動
2. 對齊(Alignment):每個AI移動時,會自動對齊鄰近AI的平均移動方向
3. 分隔(Separation):每個AI移動時,需要避開撞倒鄰近AI
有點難以置信的,只需要以上三點即可做到群聚行為
再加上兩個元素,加強AI的群聚與追蹤行為
4. 閃避(Avoidance):每個AI移動時,會避開場景上的障礙物
5. 追蹤(Chase/Intercept):即之前提過的攔截模式 + 追蹤
首先,所有的AI都需要一個或數個扇形的Sensor
來偵測『可見的』AI及障礙物
所謂可見度,就是指扇形角度以及半徑大小的意思
它也直接影響到AI群聚隊伍的『形狀』
接下來一邊移動一邊Sensor周遭的AI或障礙物
並通通把偵測到的東西都放進一個List裡面
以作為判斷下一個移動方向的依據
根據基本原理的凝聚,對齊與分隔
每次Update都會得到三個力量
這三個力量綜合即是你下一次要移動的方向
1. 凝聚(Cohesion):即Sensor到所有AI的平均位置,會得到一個點AvgPos,再得出你現在位置SelfPos與該點的相對向量AvgDirection = Vector(AvgPos - SelfPos)
2. 對齊(Alignment):這裡是取Sensor到所有AI的目前速度加總值,會得到一個合成力,Normalize後成為平均速度向量AvgVelocity
算出前兩個向量後,接下來要轉換成力量
也就是改變目前方向的力量,請見以下簡易function:
float GetDeflectForce(const NxVec3 &vMyDir, const NxVec3 &vTargetDir)
{
float fDot = vMyDir.dot(vTargetDir);
float fRadian = ConvertToRadians(fDot);
if (vTargetDir.dot(this->GetRightVector()) < 0.0f)
fRadian = -fRadian;
return fRadian;
}
3. 分隔(Separation) + 4. 閃避(Avoidance):我把這兩部份合在一起算,因為看起來差不多
即是把Sensor到所有AI加上障礙物逐一與自己目前位置比較
會得到每一個相對的距離Dist,再除以Sensor的半徑Radius,會得到一個FactorForce
把以上所有的力量加總即是AI的偏移力量,同樣見以下function
float GetAvoidForce()
{
for (it=m_lTooCloseAcotrList.begin();it!=m_lTooCloseAcotrList.end();it++)
{
pActor = *it;
vDir = pActor->getGlobalPosition() - m_pActor->getGlobalPosition();
fForce += vDir.length() / DETECT_BLOCK_RADIUS;
}
return fForce;
}
以物理學來說,就是旋轉角速度囉
到此為止,群聚的行為就已經出現了
但是群龍無首,感覺群聚行為很鬆散
此時Sensor內是空的AI,即沒有群聚行為的AI成為領導者
由它來指揮其他AI前進
於是我加了一個可控制的AI,讓領導的AI追蹤它
5. 追蹤(Chase/Intercept):攔截的部分上一篇文章已經講很多了
但有一點不一樣的是,最後算出來的預測攔截點要轉換成旋轉力量
於是再度把攔截點TargetPos,求出你現在位置SelfPos與該點的相對向量TargetDirection = Vector(TargetPos- SelfPos)
套用剛剛用到的GetDeflectForce()即可求得旋轉力
加上一點小變化
攔截模式的行為是預測,但所有AI都同樣行為未免太過呆板
於是領導的AI可選擇使用另一種追蹤:直接往目標物的位置移動
當然在這裡也需要轉換成為旋轉力量
最後就會看到兩支隊伍在追蹤
且一支隊伍是直接朝目標移動
另一支則是預測目標的行進方向,進而從中攔截
經過測試之後雖不甚滿意但勉強可以接受
可以看得出來群聚以及追蹤行為
畢竟我也不想花太多時間去修正細部行為...
這個Demo有它致命的缺點在
即,它對障礙物的真測試有限的
當碰到一片長城,AI是有可能會被卡死的
這時候就會顯的很笨....
但基本上以群聚行為來說
這樣結果算是合格了
圖片來源:http://www.red3d.com/cwr/boids/
參考資料來源:http://examples.oreilly.com/ai/
P.S 由於沒有上傳空間加上Demo也沒做多好,So有需要的人直接跟我要吧~
留言列表