Unity:プレイヤーキャラクターが近づくと追いかけてきて一定距離で停止する敵キャラクター

今回は、LookAt() 関数 と Distance() 関数を使ってプレイヤーキャラクターが近づくと追いかけてきて、一定の距離で停止する敵キャラクターオブジェクトの処理を試してみました。

シーンの作成

まず、プロジェクトにアセットストアから Standard Assets をダウンロードしてインポートします。

Standard Assets の Prototyping に含まれる床のプレハブオブジェクト FloorPrototype64x01x64 を配置。プレイヤーキャラクターとして Standard Assets の Characters に含まれる ThirdPersonController を配置しました。

ThirdPersonController に標準で設定されているマテリアルはグレーですが、以前アセットストアで公開されていたSample Assets (beta) for Unity 4.6 に含まれていたカラーマテリアルに差し替えました。

敵キャラクターはプリミティブの Capsle と Cube を組み合わせて作成。

Main Camera には Standard Assets の Utility に含まれる SmoothFollow スクリプトをアタッチ。カメラターゲットはプレイヤーキャラクターの ThirdPersonController の子階層にEmptyオブジェクトを追加して設定しました。

[Game]ビューでこのように見下ろした感じになるようカメラを設定。

敵キャラクターがプレイヤーキャラクターの方向に向かせる処理

[Project]ウィンドウ > [Create] > C# Script を選択。作成したスクリプト名を ApproachTarget に変更。このようなコードを書きました。

特定のオブジェクトの方向を向かせる関数 LookAt() を使用しています。

Transform-LookAt – Unity スクリプトリファレンス

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ApproachTarget : MonoBehaviour
{
    // ターゲットオブジェクトの Transformコンポーネントを格納する変数
    public Transform target;

    // ゲーム実行中に毎フレーム実行する処理
    void Update()
    {
        // オブジェクトを変数 target の座標方向に向かせる
        transform.LookAt(target);
    }
}

スクリプトを保存して敵キャラクターにアタッチ。Target フィールドにプレイヤーキャラクターの ThirdPersonController を割り当てます。

シーンを再生すると、プレイヤーキャラクターの座標に向かってお辞儀をしてしまいます。うーん困った。

ということで、スクリプト ApproachTarget を修正してXとY座標は自分自身の座標を参照し、Y座標だけターゲットオブジェクトを参照する処理を追加します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ApproachTarget : MonoBehaviour
{
    // ターゲットオブジェクトの Transformコンポーネントを格納する変数
    public Transform target;

    // ゲーム実行中に毎フレーム実行する処理
    void Update()
    {
        // 変数 targetPos を作成してターゲットオブジェクトの座標を格納
        Vector3 targetPos = target.position;
        // 自分自身のY座標を変数 target のY座標に格納
        //(ターゲットオブジェクトのX、Z座標のみ参照)
        targetPos.y = transform.position.y;
        // オブジェクトを変数 targetPos の座標方向に向かせる
        transform.LookAt(targetPos);
    }
}

シーンを再生して動作を確認。これでOKです。

プレイヤーキャラクターと敵キャラクターの距離によって移動停止する処理

次に敵キャラクターがプレイヤーキャラクターに近づく処理を追加します。プレイヤーキャラクターが敵キャラクターに一定距離に近づくとプレイヤーキャラクター方向に移動。一定距離近づくと停止するようにしました。

一定距離の判定を行うために2点間の距離を測る関数 Distance() を使用しています。

Vector3-Distance – Unity スクリプトリファレンス

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ApproachTarget : MonoBehaviour
{
    // ターゲットオブジェクトの Transformコンポーネントを格納する変数
    public Transform target;
    // オブジェクトの移動速度を格納する変数
    public float moveSpeed;
    // オブジェクトが停止するターゲットオブジェクトとの距離を格納する変数
    public float stopDistance;
    // オブジェクトがターゲットに向かって移動を開始する距離を格納する変数
    public float moveDistance;

    // ゲーム実行中に毎フレーム実行する処理
    void Update()
    {
        // 変数 targetPos を作成してターゲットオブジェクトの座標を格納
        Vector3 targetPos = target.position;
        // 自分自身のY座標を変数 target のY座標に格納
        //(ターゲットオブジェクトのX、Z座標のみ参照)
        targetPos.y = transform.position.y;
        // オブジェクトを変数 targetPos の座標方向に向かせる
        transform.LookAt(targetPos);

        // 変数 distance を作成してオブジェクトの位置とターゲットオブジェクトの距離を格納
        float distance = Vector3.Distance(transform.position, target.position);
        // オブジェクトとターゲットオブジェクトの距離判定
        // 変数 distance(ターゲットオブジェクトとオブジェクトの距離)が変数 moveDistance の値より小さければ
        // さらに変数 distance が変数 stopDistance の値よりも大きい場合
        if (distance < moveDistance && distance > stopDistance)
        {
            // 変数 moveSpeed を乗算した速度でオブジェクトを前方向に移動する
            transform.position = transform.position + transform.forward * moveSpeed * Time.deltaTime;
        }
    }
}

ApproachTarget スクリプトコンポーネントのパラメータ設定

編集したスクリプト ApproachTarget を保存し、アタッチした敵キャラクターの[Inspector]ウインドウでコンポーネントのパラメータをこのように設定しました。

敵キャラクターオブジェクトをプレハブに変換

敵キャラクターオブジェクトをプレハブに変換して複数配置。Standard Assets の Prototyping に含まれるプレハブオブジェクト JoinOuterPrototype02x06x02 を組み合わせてステージの壁を作りました。

WebGLビルド

今回の内容をWebGLでビルドしてみました。画像クリックでファイルがダウンロード、再生されます。(ダウンロードサイズ:約23MB)

  • キャラクター移動:前 W、左 A、後 S、右 Dキー
  • 歩く:左:Shiftキー + 移動キー
  • ジャンプ:Spaceキー
  • しゃがみ:Cキー

今回紹介した方法の問題点

今回作成したシーンでは、敵キャラクターの制御に当たり判定を組み込んでいないので障害物のすり抜けてしまい、高低差に追従していません。

キャラクターを追従して接近する一番簡単な方法は Rigidbody と NavMesh Agent コンポーネントを使用する方法ですが、今回の方法を改造する方法でもう少し考えてみたいと思います。

参考Webサイト

Unityでオブジェクトを指定の方向に向ける – Qiita

Unityで主人公キャラが近づいてきたら追いかける敵キャラを作る _ Unityを使った3Dゲームの作り方(かめくめ)

スポンサーリンク
スポンサーリンク

スポンサーリンク

フォローする

コメント

  1. たけ より:

    これは3Dのみで、2Dでは使えませんか?