Unityで色々な実験とプログラムチップ01 AIナビゲーション利用の指定ルート巡回移動

Unityで実験

本記事はゲームエンジンを利用し、様々なおもしろ理論の利活用を焦点に色々な実験結果の備忘録。あわせてオブジェクトアタッチするだけ完結プログラムチップを公開。

今回はAIナビゲーション利用の指定ルート巡回移動のプログラムチップの実験。

アタッチしたオブジェクトが、複数の指定目的オブジェクトを順番に巡回移動する。移動の軌道の計算と衝突回避の自動化部分で手抜きができる為、AIナビゲーションを利用。次のルートへは指定オブジェクトへの衝突を判定基準としている。

C# AutoMove_EnemyMove_RouteHA02_Anime.cs
using UnityEngine;
using System.Collections;
using UnityEngine.AI;


public class AutoMove_EnemyMove_RouteHA02_Anime : MonoBehaviour
{
//    public Transform target;
    private NavMeshAgent nav;
    private int size;
    private int i = 0;

    private bool Flag_sizeErr = false;
    private string objectName = "test"; 
    public Transform[] target_route;
    public string tag_name = "Player";
    Animator anim;
    // Use this for initialization
    void Start()
    {
        nav = GetComponent();
          //アタッチされたナビメッシュコンポーネットを取得
        size = target_route.Length; //Lengthで配列のサイズを取得。
      	anim = GetComponent();
    }



    void Update()
    {
        if(size > 0){ //Lengthで配列サイズが1以上の時のみ実行。エラー対応
            anim.SetFloat("Speed", nav.velocity.magnitude);
            nav.SetDestination(target_route[i].position);
            //設定されたターゲット座標をエージェントの到達座標として指示
        }else{
            if(Flag_sizeErr == false){
                Debug.Log("要素アタッチ数0"); //ログを表示 エラー対応
                Flag_sizeErr = true;
            }
        }
    }

    void OnCollisionEnter(Collision collision)     //何かに衝突した時に実行される関数
    {
       //Debug.Log(collision.gameObject.tag + " tag:side Hit! Objname = " + collision.gameObject.name);
       //ログを表示 衝突対象の名前を取得 エラー対応
       if(collision.gameObject.tag == tag_name){  //衝突対象のタグ合致したものだけ処理

       //Debug.Log("物体衝突判定:Bname = " + objectName + " Now name = " + collision.gameObject.name); //同じオブジェクトでの衝突回避
          if(objectName != collision.gameObject.name){
            if(size > 0){ //Lengthで配列サイズが1以上の時のみ実行。
                i = (i + 1) % size;
            }
            objectName = collision.gameObject.name;
          }
       }

    }

}

 

上記、プログラムチップの動作概要図解(AIナビゲーションシステムのナビマップ設定済状態で、AIエージェント設定済のキャラクターにアタッチ)

 

事前にAIに移動場所の指定で床(通常はPlaneオブジェクト)設置。インスペクターからStaticに☑を入れておく(面倒であれは全体に☑)。

その後、メニュー→Window→AI→Navigationを選択。Bakeタブ下のBakeボタンをクリック。

 

巡回させたいキャラクターにNav Mesh Agentをアタッチしておく。

その後、「AutoMove_EnemyMove_RouteHA02_Anime.cs」をアタッチ。

以下のTarget_routeで巡回ルート数を指定する。

巡回したい場所に何らかのオブジェクトを配置し、以下のElement(要素)にヒエラルキーからD&Dでアタッチする。

他のオブジェクトと区別する為に指定したTag_nameを巡回ルートオブジェクトに事前に付与しておく(挙動の幅を持たせる為。タグ名が合致しないと追跡挙動)。

※アニメーションコントローラー中のSpeedに値を渡し、停止、歩く、走るのアニメーション指示。アニメーションコントローラーを利用しない場合はSpeed関連の行のコメントアウトが必要。

実際の実行例動画 テストプロジェクト

 

使用Unityのバージョンは2021.3.7f1(LTS)。実験で上記テストプロジェクト簡易版をWebGL形式にして公開。

終了はタブを閉じる。カメラの操作方法(キーボード&マウス左ボタン)は以下。

Qキー:下降Wキー:前進Eキー:上昇マウス左ボタン:移動
Aキー:左移動Sキー:後退Dキー:右移動
Unity WebGL Player | ProgramChip_test00

 

ゲームの敵NPCの拠点防衛巡回とか、

仮想イベント会場での複数のルートと群衆グループに仕込んで群衆NPC挙動とか、

仮想アイドルコンサートのダンサーのステージ巡回とか、

仮想ファッションショーのモデルのウォーキング管理とか、

巡回キャラ自体を巡回ルートとして指定して動的なルート巡回等、

色々と利用実験できそう・・。

・・できそう。うん、そうしよう。