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

Godot 4.2:不应交互的碰撞层触发异常碰撞检测

问题分析与解决

配置信息

Godot v4.2.stable - Windows 10.0.19045 - Vulkan (Mobile) - 独立NVIDIA GeForce RTX 3080(驱动版本31.0.15.3742)- 11th Gen Intel(R) Core(TM) i7-11700KF @ 3.60GHz(16线程)

问题描述

  • 道具位于第5层,碰撞掩码仅勾选第1层(玩家)
  • 箱子位于第3层,碰撞掩码勾选第1层(玩家)、第2层(敌人)、第3层(投射物)

道具生成后立刻触发碰撞检测并消失,不符合“仅与玩家碰撞”的预期。

道具移除脚本

func _on_body_entered(_body):
    print("Item Selected", item_sel)
    print(item_sel, _body)
    if item_sel == "60" && Globals.laser_amt < 20:
        queue_free()
        print("Free")
        Globals.laser_amt = 20
    if item_sel == "15" && Globals.grenade_amt < 5:
        queue_free()
        print(Globals.grenade_amt, "Free")
        Globals.grenade_amt += 1;
    if item_sel == "20" && Globals.player_health < 100:
        queue_free()
        print(Globals.player_health, "Free")
        Globals.player_health += 20
        if Globals.player_health > 100:
            Globals.player_health == 100

层级设置

(注:原层级配置截图显示各层名称及碰撞掩码勾选状态)


核心原因与修复方案

1. 碰撞层交互逻辑校验

Godot碰撞触发的必要条件是:

A物体的碰撞层与B物体的碰撞掩码有交集,且B物体的碰撞层与A物体的碰撞掩码有交集

你描述中箱子的碰撞掩码是1、2、3层,但如果实际设置中箱子的掩码不小心勾选了第5层,就会和道具(第5层)触发碰撞。打开层级设置界面,确认箱子的碰撞掩码未包含第5层。

2. 脚本未校验碰撞对象

当前脚本只要有物体进入就执行移除逻辑,完全没判断是不是玩家。修改脚本,先过滤非玩家对象:

func _on_body_entered(_body):
    # 仅响应第1层(玩家)的碰撞体
    if not _body.get_collision_layer_bit(0): # 第1层对应索引0(Godot中层级从0开始计数)
        return
    
    print("Item Selected", item_sel)
    print(item_sel, _body)
    
    if item_sel == "60" && Globals.laser_amt < 20:
        queue_free()
        print("Free")
        Globals.laser_amt = 20
    elif item_sel == "15" && Globals.grenade_amt < 5: # 用elif避免多条件同时触发
        queue_free()
        print(Globals.grenade_amt, "Free")
        Globals.grenade_amt += 1
    elif item_sel == "20" && Globals.player_health < 100:
        queue_free()
        print(Globals.player_health, "Free")
        Globals.player_health += 20
        if Globals.player_health > 100:
            Globals.player_health = 100 # 此处是赋值操作,原代码用==判断错误

另外修复脚本里的低级错误:Globals.player_health == 100是比较运算符,应改为赋值=。

3. 避免生成位置重叠

道具生成时如果和箱子碰撞体重叠,会直接触发_on_body_entered。可以:

  • 调整生成偏移量,让道具在箱子外部生成
  • 添加短暂碰撞冷却:在道具脚本里初始化var can_pick = false,然后在_ready()中添加:
    func _ready():
        await get_tree().create_timer(0.3).timeout
        can_pick = true
    
    再在_on_body_entered开头增加if not can_pick: return。

4. 碰撞体类型确认

  • 若道具用Area2D/Area3D,确保开启了monitorable属性
  • 检查道具和箱子的碰撞体组件,确认所属节点的碰撞层、掩码设置与预期一致

内容的提问来源于stack exchange,提问作者Case

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 15:45:16