アニメーション等の準備ができたので、敵キャラが動くようにするために設定を行ったりスクリプトを作ったりしていきます。このゲームで作る敵は4種類で
- お化け:ユニティちゃんを追いかけてくる敵
- コウモリ:指定した地点を巡回する敵
- スライム:ランダムに移動する敵
- ウサギ:ユニティちゃんに一番近い地点に移動する敵
という感じにしようと思います。それではまず、このページではユニティちゃんを追いかけてくるお化けの作り方を紹介します。
障害物を避けて移動させる方法:NavMesh
さて、「ユニティちゃんを追いかける敵」ということですが…初めに「通路や障害物に引っかからないようにする方法」を考える必要があります。というのも、単純にユニティちゃんの座標めがけて移動させるだけでは、キャラがいとも簡単に障害物に引っかかってしまうからです。
そこで今回は、この問題の解決方法としてスケアクロウのチュートリアル「NavMeshを使って「追いかけてくる敵キャラ」を作る」でも紹介しているUnityの便利機能「NavMesh」というのを使います。詳しい話は今紹介したページの方をご覧いただきたいのですが、簡単に説明するとNavMeshというのは経路探索処理を簡単に実装できる機能のことです。難しい経路探索問題をわずか数行のプログラムで解決できてしまうので、これを使わない手はありません。
NavMeshの設定
NavMeshを使うためには、まずステージの地形に対してNavMeshを生成(ベイク)する必要があります。スケアクロウのチュートリアルと全く同様の手順でテスト用ステージの床にNavMeshをベイクしてみてください。
NavMesh Agentの設定
次にキャラクターに「NavMesh Agent」というコンポーネントをアタッチして設定を行います。といっても設定をいじる必要がある項目はあまりないので、とりあえず「Speed」の値を「2」、「Radius」を「1」、Heightを「2」くらいにしてください。
敵キャラクターの基底クラスの作成
そうしたら、敵キャラのC#スクリプトを書いていきます。ここでそれぞれの敵キャラには共通する部分が多いので、基底クラスを作っておいてキャラごとの処理はそれを継承したクラスで行うことにします。基底クラスのスクリプトは次の通りです。
using UnityEngine;
using UnityEngine.AI;
[RequireComponent(typeof(NavMeshAgent))]
public class BaseEnemyController : MonoBehaviour
{
protected float defaultMoveSpeed;
protected Rigidbody rigidBody;
protected GameManager gameManager;
protected NavMeshAgent agent;
protected Transform target;
protected Animator animator;
public float MoveSpeed { set; get; }
protected virtual void Start()
{
gameManager = GameObject.FindGameObjectWithTag("GameController").GetComponent<GameManager>();
agent = GetComponent<NavMeshAgent>();
animator = GetComponent<Animator>();
rigidBody = GetComponent<Rigidbody>();
defaultMoveSpeed = agent.speed;
MoveSpeed = defaultMoveSpeed;
}
protected virtual void Update()
{
if (!gameManager.countDown)
{
Stop();
return;
}
if(target != null)
{
agent.speed = MoveSpeed;
Move();
}
else
{
Stop();
}
}
protected virtual void Move()
{
animator.SetFloat("MoveSpeed", agent.speed, 0.1f, Time.deltaTime);
}
protected virtual void Stop()
{
agent.speed = 0;
animator.SetFloat("MoveSpeed", agent.speed, 0.1f, Time.deltaTime);
}
protected virtual void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.tag == "Player")
{
gameManager.GameOver();
}
}
protected void ResetMoveSpeed()
{
MoveSpeed = defaultMoveSpeed;
}
}
簡単なスクリプトなので解説する必要もないと思いますが、一応説明しておくと「ゲーム中」か「ターゲットがいない」ときは停止し、それ以外は何かしらの動きをするという処理になっています。もし敵キャラのコライダーにユニティちゃんが接触したらゲームオーバー処理を呼び出します。
追いかけてくる敵キャラのC#スクリプト
次に追いかけてくるオバケのキャラクターのスクリプトです。
using UnityEngine;
public class GhostController : BaseEnemyController
{
protected override void Start()
{
base.Start();
target = GameObject.FindGameObjectWithTag("Player").transform;
}
protected override void Move()
{
base.Move();
agent.SetDestination(target.position);
rigidBody.velocity = agent.desiredVelocity;
}
}
こちらは短いスクリプトですね。SetDestination()メソッドは「ターゲットの座標に向かって経路探索を開始するメソッド」です。それからdesiredVelocityは経路探索による期待速度なので、これをRigidBodyのvelocityに代入すればユニティちゃんに向かって移動するキャラが完成します。
次のページ→敵キャラクターの作り方3:巡回する敵
