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变量添加浮点数类型,因为现在没有初始值,它无法自动推断出类型
  • 更新函数里面根据最大值和最小值进行随机生成一个速度变量
相关推荐
sulikey2 小时前
个人Linux操作系统学习笔记6 - 操作系统与进程初识
linux·笔记·学习·操作系统·进程
unicorn313 小时前
学习学习学习
学习
XGeFei3 小时前
【Fastapi学习笔记(3)】——资源的层级关系、安全性-幂等性、Field、工厂函数
笔记·学习·fastapi
星恒随风5 小时前
Python 基础语法详解(一):从表达式、变量到数据类型
开发语言·笔记·python·学习
木斯佳5 小时前
鸿蒙开发入门指南:前端开发者快速理解视频编码概念——输入模式
华为·音视频·harmonyos
暴躁小师兄数据学院6 小时前
【AI大数据工程师特训笔记】第14讲:Linux操作系统与shell脚本
大数据·人工智能·笔记
tedcloud1236 小时前
cc-switch评测:多AI Coding Agent管理工具详解
数据库·人工智能·sql·学习·自动化
土狗TuGou6 小时前
SQL内功笔记 · 第8篇:事务的四大特性与隔离级别
数据库·笔记·后端·sql·mysql·oracle
胡图图不糊涂^_^7 小时前
测试BUG篇
学习·bug·测试
智者知已应修善业7 小时前
【51单片机用T0定时器方式1,实现0.5S的时间间隔实现第一次一个灯亮、第二次二个灯亮,直到全部灯亮,然后重复整个过程】2023-12-29
c++·经验分享·笔记·算法·51单片机