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

Godot中CharacterBody3D.get_slide_collision()返回同一实例重复碰撞问题

关于Godot 4中move_and_slide()单次调用返回同一对象多次碰撞的问题

这是预期行为吗?

是的,这种情况属于move_and_slide()的预期行为。move_and_slide()的核心逻辑是在单次物理帧内,对角色的移动路径进行多次碰撞检测与位置修正——比如当角色碰撞到物体后,会沿着碰撞法线滑动,这个滑动过程中可能会再次触发与同一对象的碰撞检测。尤其是当角色碰撞体和敌人碰撞网格存在多个接触点,或者角色在着陆瞬间的移动轨迹导致碰撞检测被多次触发时,就会生成多条指向同一collider的碰撞记录。

需要自行处理重复碰撞吗?

需要。引擎不会自动合并同一对象的碰撞记录,所以开发者需要手动添加去重逻辑,避免对同一对象重复执行处理代码(比如多次加分)。

解决方案示例

可以用一个Set来记录已经处理过的碰撞对象,遍历碰撞列表时跳过已处理的实例:

func _physics_process(delta):
    # 先执行move_and_slide
    move_and_slide(target_velocity, Vector3.UP)
    
    var processed_mobs = Set[Node3D]() # 存储已处理的敌人实例
    for index in range(get_slide_collision_count()):
        var collision = get_slide_collision(index)
        var collider = collision.get_collider()
        if collider == null or not collider.is_in_group("mob"):
            continue
        
        # 检查是否已处理过该敌人
        if collider in processed_mobs:
            continue
        
        # 验证是否是从上方踩踏
        if Vector3.UP.dot(collision.get_normal()) > 0.1:
            collider.squash() # 执行踩踏逻辑(加分)
            target_velocity.y = bounce_impulse
            processed_mobs.add(collider) # 标记为已处理

额外注意事项

  • 确保敌人的collision.squash()方法内部没有重复加分的逻辑(比如如果方法本身没做执行次数限制,即使只调用一次也没问题,但这里是多次调用导致的问题,所以去重是关键)。
  • 若敌人使用了多个碰撞体组件,也可能导致同一实例产生多条碰撞记录,这种情况同样可以用上述去重逻辑解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 19:57:28