Godot 3.3.2版本启动游戏时敌人节点消失问题求助
Godot 3.3.2 启动时敌人消失问题原因分析
1 核心触发原因
- 你编写的
_on_Area2D_body_entered信号回调逻辑存在严重问题:没有对进入碰撞区域的body做任何身份校验,只要有碰撞体进入区域,就会直接执行queue_free()销毁敌人自身 - 绝大多数情况下是敌人节点下
Area2D的碰撞层/碰撞蒙版,和自身KinematicBody2D的碰撞层/蒙版设置重叠,节点刚加入场景树的瞬间就会触发自身碰撞,直接把自己销毁,表现就是启动后立刻消失。
2 其他相关逻辑错误
- 碰撞回调逻辑冗余:你已经在
_process中做了Health <= 0时的销毁判断,不需要在碰撞回调中重复销毁自身,只需要完成扣血、销毁入射子弹的逻辑即可 - 节点实例化时机错误:你在脚本成员变量定义阶段就执行了
var explosion = load("res://Particles.tscn").instance(),此时脚本刚加载、敌人节点还没有加入场景树,实例化的粒子节点无法挂载到场景树,可能触发未知异常 - KinematicBody2D使用不规范:你在
_physics_process中直接修改position属性,之后又调用move_and_collide,会导致碰撞检测逻辑异常,KinematicBody2D的移动应该完全交给move_and_collide处理,不要直接修改position属性 - 节点获取逻辑没有容错:你直接调用
world.get_node("Player"),如果Player节点路径错误会直接抛出异常,极端情况下也会导致敌人节点被强制销毁。
修正后参考代码
extends KinematicBody2D var motion = Vector2() var Health = 100 var bullet = preload("res://Art/Bullet.png") # 不要提前实例化,只预加载场景即可 var explosion_scene = load("res://Particles.tscn") var bulletSpeed = 1000 var move_speed = 50 # 可自行调整移动速度 func _process(delta): if Health <= 0: # 死亡时再实例化爆炸效果 var explosion = explosion_scene.instance() get_parent().add_child(explosion) explosion.global_position = global_position queue_free() print(position) func _physics_process(delta): var Player = get_parent().get_node_or_null("Player") # 找不到Player时不执行移动逻辑 if not Player: return motion = (Player.position - position).normalized() * move_speed move_and_collide(motion * delta) func _on_Area2D_body_entered(body): # 只处理玩家子弹的碰撞,可根据你的实际节点名/分组调整判断条件 if body.is_in_group("player_bullet") or body.name == "PlayerBullet": Health -= 20 body.queue_free()
最后记得检查Area2D和KinematicBody2D的碰撞层、碰撞蒙版设置,确保敌人自身的碰撞层不会和Area2D的检测层重叠。
内容的提问来源于stack exchange,提问作者Catty01
相关产品推荐
相关产品推荐

