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

Godot 3.4.4 3D版本body_entered/body_exited用法示例

Godot Area与Body碰撞检测(传送模块实现)

信号核心机制

  • 你提到的body_entered/body_exited是Area节点专属的信号,父级RigidBody本身不抛出这两个信号
  • 触发逻辑:当符合碰撞规则的PhysicsBody(RigidBody/CharacterBody/StaticBody等)进入Area碰撞形状范围时触发body_entered,离开范围时触发body_exited
  • 注意:body_enter/body_exit是Godot 2时代的旧命名,Godot 3及以上版本统一使用带ed后缀的命名,写错名字信号不会触发
  • 触发必须满足的前置条件:
    • Area和目标Body的碰撞层、碰撞掩码互相匹配
    • 两者名下的CollisionShape均启用、形状参数配置正确
    • Area的monitoring属性保持开启(默认开启),目标Body的monitorable属性保持开启(默认开启)

代码挂载位置

按照你给出的节点结构,脚本直接挂载到Area子节点上即可,不需要挂在顶层RigidBody:

RigidBody
├ CollisionShape
├ MeshInstance
├ Area  # 脚本挂载到该节点
├ ├ CollisionShape

参考示例代码(Godot 4 3D版本)

extends Area

# 传送目标点,可直接在Inspector面板拖拽指定节点
@export var target_pos: Node3D
# 传送冷却,避免反复触发
var can_teleport: bool = true
@export var cooldown_time: float = 1.0

func _ready():
    # 代码内绑定信号,无需手动在编辑器连线
    body_entered.connect(_on_area_body_entered)
    body_exited.connect(_on_area_body_exited)

func _on_area_body_entered(body: Node3D):
    # 过滤需要传送的对象,比如只处理标记了player组的节点
    if not body.is_in_group("player") or not can_teleport:
        return
    # 执行传送
    body.global_position = target_pos.global_position
    # 传送后重置刚体速度,避免残留速度冲量导致错位
    if body is RigidBody3D:
        body.linear_velocity = Vector3.ZERO
    # 开启冷却
    can_teleport = false
    await get_tree().create_timer(cooldown_time).timeout
    can_teleport = true

func _on_area_body_exited(body: Node3D):
    # 无特殊逻辑可留空,通常用来处理传送后特效、状态重置等逻辑
    pass

常见问题排查

  • 如果信号完全不触发,优先检查碰撞层掩码配置:Area的碰撞掩码必须勾选目标Body所在的碰撞层
  • 2D项目逻辑完全一致,只需将对应节点替换为Area2D/RigidBody2D/CharacterBody2D,速度属性改为2D向量即可
  • 不要给Area加刚体组件,纯Area作为触发器使用即可,额外加刚体会导致碰撞逻辑异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 02:01:25