AIプログラムとかUnityゲーム開発について

探索や学習などを活用したAI系ゲームを作りたいと思います。

AIタンクにNavMeshAgentを使ってみる

 昨日のSDユニティちゃんで学んだNavMeshをAIタンクに適用してみました。


 まずマップにNavigationをbakeします。
f:id:yasu9780:20160922195430p:plain

 ランダムに画面上にターゲットを配置。
 画面上にクリックした位置にAIタンクを配置できます。
 タンクは近くのターゲットに対し、

agent.SetDestination(target.transform.position);

 で移動開始。


 ターゲットとの距離が射程範囲、かつ、視界に壁が無い場合に停止して射撃開始。

if( flag && dis<=8f && dot>=0.97f
   && !Physics.Linecast(transform.position, target.transform.position) )
{
	agent.Stop();
	status="ATTACK";

 dotは内積です(内積が1に近いほど相手が自分の正面にいる)
 射撃時は停止したいので、Stop()で経路上で一時停止します。Resume()で復帰できます。

 ちゃんと正面から射撃をしないな? と思ってたら内積計算が間違ってた。

float dot = Vector3.Dot(transform.forward, 
  target.transform.position - transform.position );

 正しくは以下。
 内積=|a||b|cosθなので、正規化しておかないと-1~1にならないので dot>=0.97fって条件が正しく動かない。

float dot = Vector3.Dot(transform.forward, 
  (target.transform.position - transform.position).normalized );


 近いターゲットの判定はpathの累積距離を求めてますが、pathPendingがtrueの場合は、単純に距離を求めています(壁を突き抜けているので不正確)
 このへんは非同期処理になるんで、ちゃんとやるとちょっと複雑ですね。


 では、実際の索敵・攻撃の様子。NavMeshすごいですね。壁にはめり込まないし、マップからは落ちないし
f:id:yasu9780:20160922200046g:plain

 NavMeshObstacleの仕組みがあるので、やろうと思えば動的にマップを作れそうですね。壊せる壁とか。


docs.unity3d.com


 NavMeshAgentのRaycastを使ったほうが良いようです
tsubakit1.hateblo.jp