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
相关产品推荐
相关产品推荐

