前言:
- 我是根据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
目标
实现:
- 玩家进入侦测范围 → 敌人切换到移动状态追击
- 可视化侦测半径
- 增加调试开关统一控制显示
一、玩家进入范围 → 切换移动状态
1️⃣ 在敌人 Idle 状态脚本顶部添加变量
var detectRadius: float = 150
2️⃣ 计算敌人与玩家距离
在 update() 或 _process() 中:
var distance = character.global_position.distance_to(player.global_position)
if distance <= detectRadius:
state_machine.change_state("Move")
原理:
- 获取敌人全局坐标
- 获取玩家全局坐标
- 用
distance_to()计算距离 - 小于侦测半径 → 切换状态
二、修复移动状态不转向问题
问题:
敌人进入 Move 后不再更新朝向。
解决:
在 Move 状态脚本里同样更新朝向逻辑:
character.updateDirection()
确保移动时也持续计算方向。
三、可视化侦测半径
1️⃣ 添加 Polygon2D 节点
- 在 Enemy 根节点下添加
Polygon2D - Ctrl+拖入 Idle 状态脚本
作用:画一个圆形范围。
2️⃣ 画圆函数
新建函数:
func drawCircle():
var points = PackedVector2Array()
var segments = 36
for i in range(segments):
var angle = deg_to_rad(i * 10)
var x = cos(angle) * detectRadius
var y = sin(angle) * detectRadius
points.append(Vector2(x, y))
polygon_node.polygon = points
说明:
- 36个点
- 每10度一个点
- 形成圆形
3️⃣ 在 enter() 中调用
func enter():
drawCircle()
不要放在 update 里,
否则每帧重绘,浪费性能。
4️⃣ 退出时清理
func exit():
polygon_node.polygon = PackedVector2Array()
5️⃣ 设置透明度
在 Inspector:
- Color Alpha = 0.25
四、添加调试开关
1️⃣ 在基础角色脚本添加
@export var showDebugVisual: bool = true
作用:
- 在检查器中出现勾选框
- 控制所有调试内容
2️⃣ 控制圆形显示
在 Idle 的 enter():
if character.showDebugVisual:
drawCircle()
else:
polygon_node.polygon = PackedVector2Array()
3️⃣ 控制状态标签显示
在 State 脚本中:
label.visible = character.showDebugVisual
4️⃣ 控制 Line2D 显示
在 Enemy 脚本中:
line2d.visible = showDebugVisual
最终效果
✔ 玩家进入范围 → 敌人自动追击
✔ 圆形显示侦测半径
✔ 方向线可视化
✔ 状态文字可控制显示
✔ 一个开关控制全部调试信息
现在敌人已经具备基础"感知 + 追击"AI逻辑。
实现过程:
- 敌人检测玩家的能力然后敌人将切换到移动状态,试图追玩家。首先我们回到敌人待机状态脚本中,在顶部添加一个新的变量是玩家侦测半径

- 我们希望当玩家进入侦测半径时,敌人能从待机状态切换到移动状态,现在来检查玩家是否足够接近,要计算敌人与玩家之间的距离,我们可以获取角色的全局位置,也就是敌人的位置,然后我们在全局位置上调用距离函数,接着我们传入玩家也就是角色点玩家,这样就能得到敌人到玩家的距离。根据距离进行切换状态

- 另外我们测试的时候会发现敌人进入到移动状态之后,玩家进行移动是,它没有转方向,所以我们来单移动状态脚本中加一下

- 接着我们来可视化一下敌人的侦测半价,然后后面就可以用这个技巧来可视化游戏中你想查看的其他属性。我们回到敌人场景在根节点添加一个新的子节点Polygon2D

- 我们可以用它来绘制一个圆形,代表玩家的探测范围。我们按住ctrl+拖动将这个节点拖动到待机状态脚本中

- 然后我们新建一个函数,来进行画圆,我们先创建一个点的数组,这个节点的创建数组是一个特殊的函数

- 接下来创建圆的点,利用循环创建36个点

- 接着在设置节点的多边形属性

- 我们是在inter函数中进行使用绘画而不是update函数中做这个操作这样敌人进入空闲状态时我们只绘制一次圆形。

- 同时我们也希望在敌人退出空闲状态时清理这个圆形

- 然后我们来设置一下这个节点画的圆的透明度为25

- 接着启动游戏就可以看见了

- 然后我们调试的东西往后会越来越多,所以我们需要有一个开关的选项进行控制调试信息的显示!我们去基础角色脚本里添加一个变量来实现这个功能。
- 我们声明一个名为showDebugVisual的新变量,并把默认值设为true并且加入export的注解,曝光在节点的检查器上

- 然后我们回到待机状态脚本中,我们在进入函数添加一个if检测,只有在showDebugVisual为true时才创建圆圈以及清理圆

- 另外在在没有开启调试的时候我们要在进入函数那里进行清理多边形的所有点

- 另外我们希望这个调试的开关按钮也影响状态标签文本的出现,所以我们到状态脚本中进行重写一下代码

- 另外把关于line2d线的出现与隐藏也进行控制一下,回到敌人场景脚本中
