Godot中实现敌人冲过玩家后切换射击状态的代码问题求助
问题排查与修复方案
核心问题分析
你的代码中_on_Timer_timeout()里的目标点计算逻辑错误,生成的target并非基于玩家位置的冲过点,而是从世界原点出发的向量,导致敌人移动完全不符合预期。另外,直接用position==target判断到达状态,会因浮点数精度问题出现判断失效的情况。
修复步骤
1. 修正目标点计算逻辑
正确的冲过玩家的目标点,应该是从敌人当前位置出发,朝着玩家方向移动并越过玩家一段距离。以下两种计算方式任选其一:
方式一:基于玩家位置延伸固定距离
func _on_Timer_timeout(): # 获取敌人指向玩家的单位方向向量 var direction = (Global.player_pos - position).normalized() # 自定义冲过玩家的额外距离(数值可根据需求调整) var overshoot_distance = 200 # 目标点 = 玩家位置 + 方向向量 × 额外冲过距离 target = Global.player_pos + direction * overshoot_distance shoot_on = false
方式二:基于敌人到玩家的距离按比例延伸
func _on_Timer_timeout(): var direction = (Global.player_pos - position).normalized() # 计算敌人与玩家的当前距离 var distance_to_player = position.distance_to(Global.player_pos) # 冲刺总长度为原距离的1.4倍(系数可自由调整) var total_dash_length = distance_to_player * 1.4 # 目标点 = 敌人当前位置 + 方向向量 × 总冲刺长度 target = position + direction * total_dash_length shoot_on = false
2. 修复到达目标点的判断逻辑
用Godot内置的is_equal_approx()替代直接相等判断,规避浮点数精度问题:
func _physics_process(delta): if shoot_on == false: position = position.move_toward(target, delta * speed) # 用近似相等判断替代直接== if position.is_equal_approx(target): shoot_on = true target = Vector2.ZERO $Timer.start() launch_proximity()
完整修复后代码示例
func _physics_process(delta): if shoot_on == false: position = position.move_toward(target, delta * speed) if position.is_equal_approx(target): shoot_on = true target = Vector2.ZERO $Timer.start() launch_proximity() func _on_Timer_timeout(): var direction = (Global.player_pos - position).normalized() # 这里采用固定冲过距离的方式,可自行替换为比例延伸逻辑 var overshoot_distance = 200 target = Global.player_pos + direction * overshoot_distance shoot_on = false # 已实现的激光发射函数 func launch_proximity(): # 你的激光发射逻辑代码
额外优化建议
- 将冲过距离/比例系数设为导出变量,方便在编辑器中实时调整测试:
@export var overshoot_distance: float = 200 - 如果敌人移动速度过快,可在
move_toward中限制单次移动的最大距离,避免跳过目标点。
内容的提问来源于stack exchange,提问作者Binbows
相关产品推荐
相关产品推荐

