在范围内追逐
本课属于 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 会记住敌人是否正在追赶,而在两个范围之间时,这个状态不会改变,因此敌人会继续之前的行为。
挑战
中等让狼在玩家靠近时注意到玩家,并在玩家远离时放弃追逐。
- 在
FixedUpdate()中,计算到玩家的水平距离:小于noticeRange时,将bool chasing字段设为true;大于giveUpRange时,设为false。 - 追逐时,将
rb.linearVelocity设为朝向玩家、速度为speed的值,同时保留 y 值。 - 否则,将
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 在线编辑器