2013年2月3日日曜日

Unityで初めてのAIキャラクター(7.しゃがんで隠れる(隠れる場所を探す))

※ 2013/2/11時点で元記事のうち、この章のみ削除されました

さて、いよいよ本シリーズの最終記事だ。敵キャラも隠れた位置をみつけて、そこからこちらに向けて撃っていく、そういう場面のコーディングで総仕上げといこう。

関連記事


では例のごとく、Unity Gemsからの翻訳をどうぞ!



November 22, 2012

しゃがんで隠れる(隠れる場所を探す))


最後のセクションは良く戦争モノのゲームである場面だが、敵が遠く離れている場合、どこかに隠れ場所を見つけて、そこに隠れながら撃つ動作をする。時々、別の場所に敵は別の地点に移動をして(プレイヤーはこのときにNPCをやっつけるチャンスなので重要だ)。では関数を定義して、どの場所が安全で、プレイヤーとの距離はどこが一番近いかをチェックしていく。

そこでゲーム上での安全な場所を、おそらくは隠れられる何かのすぐ後ろなどに見つけて Safe (安全) とタグ付けする。次にそういう場所の中で最も近い場所を得る関数が必要だ。そこから安全な場所とプレイヤーとの距離をみて、もしその地点の方ご近ければそこに移動して撃ち始める。
Transform safePlace;
void FindClosestSafe() {
        GameObject[] gos;
        gos = GameObject.FindGameObjectsWithTag("Safe");
        GameObject closest=null;
        float distance = Mathf.Infinity;
        Vector3 position = transform.position;
        foreach (GameObject go in gos) {
            Vector3 diff = go.transform.position - position;
            float curDistance = diff.sqrMagnitude;
            if (curDistance < distance) {
                closest = go;
                distance = curDistance;
            }
        }
        safePlace =  closest.transform;
    }
それによって最も近い安全な場所を取得出来るようになる。それでは TakeCover 関数がさらに必要だ。
void TakeCover(){
    if((_transform.position - safePlace.position).sqrMagnitude >range ){
            Move(safePlace);
            animation.CrossFade("walk");
        }else{
            print ("ズキュン ズキュン!!");
        }
    }
これは単に安全な場所に移動して着いたら撃ち始めるというだけだ。着いた瞬間にズキュン ズキュンといくわけだが、まあ要領は分かってもらえるとおもう。

最後に、AIFunction関数にコードを追加する:
bool AIFunction(){
   if((_transform.position - player.position).sqrMagnitude < attackRange &&
         Vector3.Angle(player.transform.position - _transform.position, transform.forward) <= angle){
      if (!Physics.Linecast (_transform.position, player.position, layerMask)){
         FindClosestSafe() ;
         Vector3 a = safePlace.position - _transform.position;
         Vector3 b = player.position - _transform.position;
         if(a.sqrMagnitude < b.sqrMagnitude){
            _delFunc = this.TakeCover;
         }else{
            _delFunc = this.Attack;
         }
      }
      return true;
   }else{
      _delFunc = this.Walk;
      return false;
   }
}
これで完成だ!!!

そしてこのチュートリアルで作り上げた完成コードを掲載する:

完成した短いコード(クリックして展開)


これでチュートリアルもほぼ終わりまで来たわけだが、デリゲートによって様々なことが容易になったことに気付いてもらえただろうか。関数をいくつか追加きたにも関わらず、Update関数は変更せずに済んでいる。デリゲートのお陰でNPCキャラクターのメイン関数を変更することなく、ビヘイビアを追加出来るのだ。

結論


これでNPCキャラクターについて、さらに開発を進めるための基本は覚えたといってよい。これが皆さんの役に立って、さらに発展的なデリゲートのチュートリアルに進んでいくための手助けになれば、と願う。

さらに敵キャラが壁や木をすり抜けたりせずに動き回らせる方法をみてきた。敵キャラがプレイヤーを視界に入れて走ってくるもカバーした。また簡単なデリゲートについても学んだ。後はこの知識を活かしてさらに高度なことを実現してもらいたい。

今回のチュートリアルも気に入ってもらえたら何よりだ。
------


※ 2013/2/11時点で元記事のうち、この章のみ削除されました。

プロジェクトサンプルはアップしていただけました!目次ページを参照ください。


プロジェクトファイルを公開してもらえるように Mike Talbot氏にお願いしてて今週のどこかにはアップロードしてくれるとのこと。楽しみだな~

先人の知恵を活用して開発していこうぜ!

0 件のコメント:

コメントを投稿

ブックマークに追加

このエントリーをはてなブックマークに追加

自己紹介

自分の写真
Unity3D公式マニュアル翻訳やってる人がスマホ(iPhone, Android)のゲーム開発しています。気軽に面白く初心者が遊べる内容がモットー。Blogでは開発情報をひたすら、Twitterではゲーム作成の過程で参考にしている情報を中心につぶやきます

ページビューの合計

過去7日間の人気投稿