Godot 4中CharacterBody2D敌人AI移动异常问题求助
问题解决方案
问题原因分析及修复步骤
- 玩家跳跃时敌人瞬移:原代码计算的方向包含Y轴分量,敌人会试图向玩家的Y轴位置移动,加上未用
delta控制移动步长,导致移动幅度异常。 - 地面移动速度极慢:原代码移动时未乘以
delta,实际移动速度是每帧固定值,而非每秒设定的速度值。 - 空中抖动穿墙:敌人试图向玩家Y轴位置移动,加上
move_and_collide的碰撞处理方式不适合持续移动场景,导致碰撞异常。
修改后的完整代码
var speed = 1000 # 可选:添加地面检测的区域节点引用 @onready var ground_check = $GroundCheckArea func _physics_process(delta: float) -> void: move_towards_closest_player(delta) func move_towards_closest_player(delta: float) -> void: # 处理玩家组为空的情况 var players = get_tree().get_nodes_in_group("player") if players.empty(): return var closest_player = players[0] var closest_distance = INF # 遍历寻找最近玩家 for player in players: if player == null: continue var distance = abs(player.global_position.x - global_position.x) if distance < closest_distance: closest_distance = distance closest_player = player if closest_player == null: return # 仅保留X轴方向,Y轴设为0 var direction = Vector2(closest_player.global_position.x - global_position.x, 0).normalized() # 计算移动速度,乘以delta保证帧率无关 velocity = direction * speed # 可选:仅在地面时移动 if is_on_floor() or (ground_check and ground_check.is_overlapping_body()): move_and_slide() else: velocity.x = 0
关键修改说明
- 限制X轴移动:将方向向量的Y分量强制设为0,确保敌人仅沿水平方向移动,不再跟随玩家的垂直位置。
- 帧率无关的速度计算:移动速度乘以
delta,保证无论帧率如何,敌人每秒移动距离都是设定的speed值。 - 替换移动方法:使用
move_and_slide替代move_and_collide,该方法专门为CharacterBody2D设计,自动处理碰撞和滑动,减少穿墙和抖动问题。 - 优化玩家查找:先获取玩家组并判断是否为空,避免空数组访问报错;遍历过程跳过空节点,提升稳定性。
- 地面检测(可选):添加地面检测逻辑,确保敌人只在地面时移动,避免空中出现异常行为。
内容的提问来源于stack exchange,提问作者Flapjaq
相关产品推荐
相关产品推荐

