You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 09:27:04