範囲内で追いかける
CoddyのUnityジャーニー「物理演算とゲームプレイ」セクションの一部。レッスン 51/63。
ほとんどの敵は、近づくまでは放っておいてくれます。物理演算の各ステップでプレイヤーとの距離を測り、一定の範囲内にいるときだけ追いかけます。このスライムはsightRange内で追いかけ、その範囲外では立ち止まります。
void FixedUpdate()
{
Vector3 toPlayer = player.position - rb.position;
toPlayer.y = 0f;
if (toPlayer.magnitude < sightRange)
{
Vector3 dir = toPlayer.normalized;
rb.linearVelocity = new Vector3(dir.x * speed, rb.linearVelocity.y, dir.z * speed);
}
else
{
rb.linearVelocity = new Vector3(0f, rb.linearVelocity.y, 0f);
}
}elseは重要です。Rigidbodyは、何かによって変化させられるまで速度を保ちます。これがないと、プレイヤーを見失ったスライムは摩擦で止まるまで滑り続け、氷の上では決して止まりません。最初にyを0にしているため、toPlayer.magnitudeは地面に沿った距離になります。つまり、スライムの隣にある木箱の上に立っているプレイヤーも、隣にいると判定されます。
範囲を1つだけにすると、弱点があります。その境界に立っているプレイヤーは範囲の内外を行き来し、スライムは何度も動き出したり止まったりします。敵は2つの範囲を使ってこれを防ぎます。短い範囲内でプレイヤーに気づき、より長い範囲の外に出たときだけ追跡を諦めます。boolで敵が追跡中かどうかを記憶し、2つの範囲の間ではその状態を変えないため、敵はそれまでの行動を続けます。
チャレンジ
中級オオカミが森で狩りをしています。WolfにWolfスクリプトを書きます。Inspectorでplayer、speed(3)、noticeRange(4)、giveUpRange(8)を設定します。Playerスクリプトは準備できています。
chasingという名前のboolフィールドは、オオカミが追いかけているかどうかを示します。初期値はfalseです。- 物理演算の各ステップで、地面に沿ったプレイヤーとの距離を測定します(高さは含めません)。
noticeRangeより近い場合、chasingはtrueになります。giveUpRangeより遠い場合、falseになります。その間は、現在の状態を保ちます。 - 追いかけている間、オオカミはRigidbodyを使い、y速度を維持しながら
speedでプレイヤーに向かって走ります。それ以外の場合は静止し、x速度とz速度は0になります。
Playを押し、オオカミに近づいてから逃げ、その後Checkを押します。
自分で試してみよう
using UnityEngine;
public class Wolf : MonoBehaviour
{
[SerializeField] private Transform player;
[SerializeField] private float speed = 3f;
[SerializeField] private float noticeRange = 4f;
[SerializeField] private float giveUpRange = 8f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
// playerを見つけるか追跡を諦めるかを判断し、追いかけるかその場にとどまる
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。