Godot3.3.2报错:刷新查询时无法改状态,敌人死亡碰撞框不消失
问题解决方案
报错原因
Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead
该报错是Godot物理引擎的固有规则:当引擎处于物理帧的碰撞查询刷新阶段时,禁止直接修改碰撞体的启用/禁用状态。你触发报错的原因是在碰撞检测相关的回调逻辑中直接执行了$CollisionShape2D.disabled = true代码,刚好命中了物理查询的刷新周期。
修复步骤
- 替换碰撞框禁用的实现方式,使用
set_deferred延迟修改属性,等物理查询阶段结束后引擎会自动执行修改操作 - 优化
_physics_process的逻辑,敌人死亡后不再执行墙体检测、射线检测逻辑,避免无效操作
修改后的完整代码
extends KinematicBody2D const GRAVITY = 10 const SPEED = 30 const FLOOR = Vector2(0, -1) var velocity = Vector2() var direction = 1 var is_dead = false func _ready(): pass func dead(): is_dead = true velocity = Vector2(0, 0) $AnimatedSprite.play("dead") # 替换为延迟调用修改碰撞框属性 $CollisionShape2D.set_deferred("disabled", true) $Timer.start() func _physics_process(delta): if is_dead == false: velocity.x = SPEED * direction if direction == 1: $AnimatedSprite.flip_h = false else: $AnimatedSprite.flip_h = true $AnimatedSprite.play("walk") velocity.y += GRAVITY velocity = move_and_slide(velocity, FLOOR) # 把检测逻辑移到死亡判断内,死后不再执行 if is_on_wall(): direction = direction * -1 $RayCast2D.position.x *= -1 if $RayCast2D.is_colliding() == false: direction = direction * -1 $RayCast2D.position.x *= -1 func _on_Timer_timeout(): queue_free()
内容的提问来源于stack exchange,提问作者Snaza
相关产品推荐
相关产品推荐

