godot2D游戏教程系列二(25)

前言:


目标

使用 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变量添加浮点数类型,因为现在没有初始值,它无法自动推断出类型
  • 更新函数里面根据最大值和最小值进行随机生成一个速度变量
相关推荐
知产xiao_xin17 分钟前
知识产权入门 —— 版权
经验分享·笔记·知识产权
一条破秋裤18 分钟前
02_软件安装与新建工程
学习
来了就未晚31 分钟前
Python基础 学习代码存储与命名规范
开发语言·python·学习
GHL28427109033 分钟前
用codex做一个简单技能学习
学习·ai
呆萌很41 分钟前
英语 1‑12 月单词联想记忆
笔记
Dovis(誓平步青云)1 小时前
折叠屏悬停看视频,上半屏和下半屏应该各做什么
android·java·服务器·开发语言·安全·音视频
西西弗Sisyphus2 小时前
模型训练 不同批次大小与学习率下的训练损失对比(2)
学习·batchsize·lr·learning rate
软件开发技术深度爱好者2 小时前
在线学习实践 TypeScript 的官方Playground(演练场)使用介绍
javascript·学习·typescript
我想我不够好。2 小时前
豹女q w e r衔接闪现
学习
金立基包装胶水2 小时前
纸袋热封频繁不良,先排查胶料这一堆问题
大数据·笔记·其他