前言:
- 我是根据b站上的视频进行学习,并且总结写下笔记,然后做此分享。笔记非常详细以至于你可以通过查看文章进行快速学习并且制作出游戏出来。当然视频学习的链接我也放在下面了:
- 视频学习:https://www.bilibili.com/video/BV1Nd25BNEA6?spm_id_from=333.788.player.switch\&vd_source=078d5d025b9cb472d70d8fda1a7dc5a6\&p=15
- 音频/美术资源包下载: https://pan.baidu.com/s/1mY05SbG3XFUpn-qiKxDRhw?pwd=b6bg
目标
使用 NavigationAgent2D 避让功能:
- 敌人之间保持距离
- 不互相重叠
- 随机移动速度
- 修复速度叠加问题
一、开启避让功能
选中 Enemy 场景里的 NavigationAgent2D:
在 Inspector 中:
- ✅ 启用 Avoidance
- Radius = 30 → 扩大检测碰撞范围
- Max Speed = 20 → 避让时的移动速度
作用:
当敌人靠近时自动计算"安全速度"。
二、连接避让信号
使用信号:
velocity_computed(safe_velocity)
双击该信号 → 添加到 移动状态脚本。
三、在信号函数中处理避让
func _on_navigation_agent_2d_velocity_computed(safe_velocity: Vector2):
if state_machine.current_state != self:
return
character.velocity = safe_velocity
⚠ 为什么不能叠加?
错误写法:
character.velocity += safe_velocity * delta
问题:
- 每帧累加
- 速度会不断增加
- 敌人会突然弹开
正确做法:
- 直接使用 safe_velocity
- 或者使用 lerp 平滑过渡
四、给敌人随机移动速度
1️⃣ 定义常量
const SPEED_MIN = 60
const SPEED_MAX = 120
2️⃣ 声明 speed 类型
var speed: float
⚠ 必须写类型,因为没有默认值。
3️⃣ 在 enter() 中随机生成
func enter():
speed = randf_range(SPEED_MIN, SPEED_MAX)
timer.start()
说明:
- 每个敌人进入移动状态时
- 生成不同速度
- 行为更自然
五、完整移动逻辑结构
1️⃣ Timer 更新目标位置
每 0.5 秒更新:
nav_agent.target_position = player.global_position
2️⃣ physics_update 里
var next_path_position = nav_agent.get_next_path_position()
direction = (next_path_position - character.global_position).normalized()
nav_agent.velocity = direction * speed
注意:
- 现在使用 nav_agent.velocity
- 不直接改 character.velocity
3️⃣ velocity_computed 信号中
character.velocity = safe_velocity
character.move_and_slide()
最终效果
✔ 敌人之间自动分开
✔ 不会重叠
✔ 不会速度叠加爆炸
✔ 每个敌人移动速度不同
✔ 行为更自然
现在敌人具备:
- 寻路
- 避让
- 追击
- 随机移动速度
已经是完整可扩展的基础 AI 系统。
实现过程:
- 我们不希望敌人彼此重叠在一起,所以在这节课中,我们将利用导航系统的避让功能,让敌人之间保持一定的距离。
- 敌人场景选中2d导航代理节点,到右边检查器启用避让功能,然后把半径属性增加到30,这样会让避让检测的碰撞体变得更大,另外把最大速度变为20,这个数值定义敌人在视图躲避其他敌人时的移动速度

- 另外采用节点的velocity computed的信号,这就是躲避功能的工作原理,当这个敌人需要躲避其他敌人时,这个信号函数会被自动调用

- 我们需要将这个安全速度与敌人的当前速度进行整合,这样它就能尝试避开其他敌人,让我们双击这个信号将其添加到敌人移动状态脚本中

- 我们需要假设这个函数可能在敌人处于其他状态时被调用,所以首先检查父状态机的当前状态是否为这个移动状态,然后我们可以通过将安全速度加到角色速度上来更新角色的速度,移动过程是平滑的所以将其乘以增量时间

- 然后我们会发现当玩家等待 当敌人在同一位置停留一会儿后玩家移动时它们会迅速分散开来,这是因为我们将安全速度叠加到敌人的速度上会随着时间累积。

- 接下来让我们为每个敌人随机设置移动速度,我们声明一个名为SPEED_MAX,SPEED_MIN的常量,另外把之前的速度的变量注释掉

- 我们还需要为speed变量添加浮点数类型,因为现在没有初始值,它无法自动推断出类型

- 更新函数里面根据最大值和最小值进行随机生成一个速度变量
