Menu
CoddyTech

在范围内追逐

本课属于 Coddy Unity 学习旅程的“物理与游戏玩法”单元。第 53 课,共 71 课。

大多数敌人会等你靠近后才理你。在每个物理步骤中计算你与玩家之间的距离,只在一定范围内追赶。这个史莱姆会在 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 表示地面上的距离,因此即使玩家站在史莱姆旁边的箱子上,也仍然算是在它旁边。

只设定一个范围有个缺点。玩家站在范围边缘时,会时进时出,史莱姆就会反复开始和停止。敌人会用两个范围来避免这种情况:玩家进入较小的范围时,它们会注意到玩家;只有玩家超出较大的范围时,它们才会放弃追赶。bool 会记住敌人是否正在追赶,而在两个范围之间时,这个状态不会改变,因此敌人会继续之前的行为。

challenge icon

挑战

中等

让狼在玩家靠近时注意到玩家,并在玩家远离时放弃追逐。

  1. 在 FixedUpdate() 中,计算到玩家的水平距离:小于 noticeRange 时,将 bool chasing 字段设为 true;大于 giveUpRange 时,设为 false。
  2. 追逐时,将 rb.linearVelocity 设为朝向玩家、速度为 speed 的值,同时保留 y 值。
  3. 否则,将 rb.linearVelocity = new Vector3(0f, rb.linearVelocity.y, 0f); 设为速度。

按下 “开始”,走到狼附近,然后跑开。接着点击 “检查”。

亲手试试

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()
    {
        // 发现玩家,决定是否放弃追逐,然后追赶或保持不动
    }
}

物理与游戏玩法中的所有课

自己练习: Unity 在线编辑器