oneywa 发表于 2025-5-19 20:23:40

godot又双求助

c# godot求助,碰撞函数没有启用(没有报错)
using Godot;
using System;
using System.Threading.Tasks;

public partial class Enemy : CharacterBody2D
{
    // 敌人变量
    public int health;
    public int attack;
    public float speed;
    public CharacterBody2D player;


    private AnimationPlayer animation;
    private Label label;
    private bool is_destruction = false;
    private bool is_attacking = false;

    public override void _Ready()
    {
      base._Ready();
      GetNode<Area2D>("Destruction").BodyEntered += OnDestructionBodyEntered;
    }


    public override void _EnterTree()
    {
      base._EnterTree();
      animation = GetNode<AnimationPlayer>("AnimationPlayer");
      player = GetNode<CharacterBody2D>("/root/Main/Player");
      label = GetNode<Label>("/root/Main/Hud/Label2");
    }


    public override void _Process(double delta)
    {
      base._Process(delta);

      

      Move((float)delta);
      if (!is_attacking)
      {
            MoveAndSlide();
      }

      for (int i = 0; i < GetSlideCollisionCount(); i++)
      {
            KinematicCollision2D collision = GetSlideCollision(i);
            GodotObject collider = collision.GetCollider();
      }

      // 自爆
      if (Position.DistanceTo(player.Position) <= 100.0f && is_destruction == false)
      {
            Destruction();
      }

      if (health <= 0)
      {
            QueueFree();
      }
    }

    // 移动
    private void Move(float delta)
    {
      LookAt(player.Position);

      Vector2 direction = Vector2.Right.Rotated(Rotation).Normalized();
      Vector2 movement = direction * speed * (float)delta;
      Velocity += movement;
    }

    private void OnDestructionBodyEntered(Node2D body)
    {
      GD.Print("a");
      if (body == player && is_attacking == false)
      {
            GD.Print("b");
            is_attacking = true;
            player.Set("health", (int)player.Get("health") - attack);
            label.Set("score", (int)label.Get("score") + 1);
      }
    }


    private async Task Destruction()
    {
      is_destruction = true;
      animation.Play("destruction");
      Timer time = new Timer();
      time.WaitTime = 0.15f;
      AddChild(time);
      time.Start();

      await ToSignal(time, "timeout");

      QueueFree();
    }
}

FishC 发表于 2025-5-19 20:24:29

关于Godot碰撞检测未触发的问题排查

以下是常见原因和解决方案:

1. 碰撞层设置问题
检查Destruction区域节点的Collision Layer/Mask是否与目标物体的Layer匹配:

// 在_Ready()中可动态设置(示例)
GetNode<Area2D>("Destruction").CollisionMask = 1; // 设置检测第1层


2. 节点类型问题
确保"Destruction"节点是Area2D类型而不是静态碰撞体

3. 信号连接问题
建议改用Godot编辑器的可视化信号连接:

[*]在场景面板右键Destruction节点
[*]选择"连接到信号"
[*]选择BodyEntered信号
[*]连接到Enemy脚本


4. 监控状态问题
检查Area2D的Monitoring属性是否开启

5. 参数类型问题
将事件处理方法改为:

private void OnDestructionBodyEntered(Node2D body)
{
    GD.Print("碰撞检测到:" + body.Name);
    // 添加你的逻辑...
}


6. 调试建议
在方法内添加打印语句测试是否触发:

private void OnDestructionBodyEntered(Node2D body)
{
    GD.Print("[碰撞触发] 对象:", body.Name);
    // 其他逻辑...
}


7. 移动逻辑冲突
检查是否在移动时覆盖了碰撞位置,可尝试注释掉MoveAndSlide()测试

其他注意事项:

[*]确保目标物体至少有一个CollisionShape2D
[*]检查场景中所有节点的可见性(Hidden属性是否关闭)
[*]运行时可打开Godot的调试 -> 可见碰撞体辅助调试


以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: godot又双求助