ゾンビを実装
主人公を追いかける「ゾンビ」を実現しましょう!
シーンの設定
ゲームオブジェクトと3Dモデル
Timmyと同様に、ゾンビのゲームオブジェクトを作成しましょう。空のゲームオブジェクトを作成し、その下に子オブジェクトとしてZombieのモデルを追加する:

ただし、ゾンビは物理的に動かないので、コライダーとリジッドボディが要らない。ゾンビの動かした方については、下記で説明する。
アニメーション
今回は、アニメーションは1つしかなくて、ずっと歩くようにしましょう。ただし、Timmy と同様に「アバター」の設定が必要。


そして、ゾンビのアニメーターコントローラーを作成し、「ZombieWalk」のアニメションをデフォルトにする

これで実行してみてください(ループを忘れずに~)
自動的に道を探す「ナビゲーション」
人間を制御するキャラクターが、当たり判定を確認するだけで、動きの実装ができる。人間が勝手に障害物などを避けて動く。一方、CPUキャラクターがとても馬鹿であり、障害物を避けたらすることができない。
この問題を解決するには、Unityが「Navigation」(ナビゲーション)を提供する。ナビゲーションとは、自動車のナビと同じように、目的地を設定し、最適なルートを探す処理である。
ナビゲーションは以下の主なコンポーネントを組み合わせて、作成する
その他にも、ナビゲーションの影響にあるコンポーネント(NavMesh Link、NavMesh Obstacle、など)もあるが、最低限でこの2つの組み合わせで十分。
ナビゲーションメッシュ(NavMesh Surface)
ナビの地図である。地図を作るのは、シーンを固定してから!シーンが変わったら(壁を増やした、障害物の位置を変えた)、地図も更新しないといけないので、ご注意ください。
まず、地図に使うオブジェクトをグループ化にしないといけないので、シーンを整理し、ゾンビと主人公の間にいくつかの壁を作ってみましょう。空ゲームオブジェクト「Stage」を作成し、中には床面、ランプそして新しい壁を追加してください。

ここで「ナビゲーションメッシュ」を作りましょう。「Stage」を選択し、「NavMesh Surface」を追加してください

ここで地図を作る時に必要なパラメータを設定できるが、最も重要なのは、何を基づいて地図を作るのか。これは「Object Collection」から設定ができる。今回は「Stageとその子オブジェクトを使用」にしたいので「Current Object Hierarchy」(現在オブジェクトのヒエラルキー)を選択しましょう。
そして、ナビゲーションメッシュを作成するには「Bake」(焼く)ボタンを押すだけ。このボタンを押すと、Stageとその子オブジェクトのすべてを処理し、歩ける「地図」を水色で表示される:

壁にあまり近づかないよう、周囲に「歩けない」領域が現れる。この地図が焼いているので、ステージが変わっても地図が変わらない! 1つの壁を削除しても、「歩けない」領域が残る:

ナビゲーションメッシュを焼いた後にシーンが変わったら、もう一度「Bake」してください。
エージェント(NavMesh Agent)
エージェントは、水色の「地図」(ナビゲーションメッシュ)上で歩くものである。目的地を設定すれば、現在地から最適な道を探し、自動的に動く。
今回のゲームで、ゾンビが動いてほしいので、エージェントにしましょう。ゾンビ(親オブジェクト)に「NavMesh Agent」を追加してください。

ここでエージェントのパラメータを調整ができる。主なパラメータは:
| Base Offset(基礎オフセット) | 足元からの「ずれ」 |
| Speed(速度) | 移動速度 |
| Angular Speed(回転速度) | 向きを変える速度 |
| Acceleration(加速度) | 加速と減速の速さ |
| Stopping Distance(停止距離) | 目的地までこの距離になったら止まる |
| Radius(半径) | エージェントの「太さ」 |
| Height(高さ) | エージェントの「身長」 |
とりあえず、ゾンビの速度を「1」にし、残りのパラメータをそのままにしましょう。
スクリプト
プレーヤーを追いかける
スクリプトは、プレーヤーの位置を求め、エージェントの目的地を設定するだけ。「PlayerChase」のスクリプトは以下の通りである:
using UnityEngine;
using UnityEngine.AI;
// プレーヤーを追いかける
public class PlayerChase : MonoBehaviour
{
// 追いかけるプレーヤー
private GameObject player;
// エージェントの目的地を設定するため
private NavMeshAgent agent;
private void Start()
{
// 後ほどプレハブにするので、Unityで紐づけせず、
// 実行中にプレーヤーを探す
player = GameObject.Find("Player");
// NavMeshAgentのコンポネント取得
agent = GetComponent<NavMeshAgent>();
}
private void Update()
{
// 追いかける
// SetDestination はエージェントの目的地を設定するメソッド。
// 引数はその位置である(プレーヤーの位置)
agent.SetDestination(player.transform.position);
}
}
このスクリプトを Zombie にアッタッチし、実行してみてください。
Timmyの体力
これで、追いかけるようになったが、ゾンビが主人公を捕まっても、なにもならない。Timmyの体力を実装しましょう。「HitPoints」のスクリプトは以下の通りである:
// 体力を管理するクラス
public class HitPoints : MonoBehaviour
{
// 体力
private int hp = 3;
}
当たり判定とダメージ
ここでトリガーを活用ができる。もし、HitPoints がダメージの起源(ゾンビ、罠、炎など)と重なったら、ダメージを受ける。どれぐらい受けるのかをその「ダメージの起源」(DamageSource)で指定ができる

まず、ダメージの起源を作成しましょう:
// ダメージの起源
public class DamageSource : MonoBehaviour
{
// ダメージの量
[SerializeField]
private int damage;
// ダメージの量(読み込む専用)
public int GetDamage()
{
return damage;
}
}
そして、HitPoints スクリプトは:
// 体力を管理するクラス
public class HitPoints : MonoBehaviour
{
// 体力
private int hp = 3;
// トリガーに入ったら
private void OnTriggerEnter(Collider other)
{
// ダメージの起源かどうかを確認
DamageSource src = other.GetComponent<DamageSource>();
if (src == null)
return;
// 体力を減らし、0 以下にならないように制限する
hp = Mathf.Max(0, hp - src.GetDamage());
}
}
確認
確認するには、ゾンビにダメージの起源を追加しなければならない。Zombieに新しい子オブジェクトを追加し、トリガーと DamageSource を追加してください

そして、Player に HitPoints を追加し、Debug.Log で体力を表示してください。