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

Sprite碰撞检测异常:触碰碰撞体时瞬移至另一侧

问题分析与解决方案

核心问题:错误的motion参数导致瞬移

你用move_and_collide(velocity * (1 / delta))完全搞反了速度和位移的关系:

  • move_and_collide需要的参数是单帧内要移动的绝对位移量(motion),不是速度。
  • 速度的定义是「单位时间内的位移」,正确的单帧位移应该是 速度 * 帧时间(delta),而非速度 / delta。你之前的写法把单帧位移放大了几十倍(比如60帧下delta≈0.016,1/delta≈60),相当于让Sprite一帧就冲出去好远,碰到碰撞体时,引擎的碰撞校正会直接把Sprite推到碰撞体另一侧,看起来就是瞬移。

鼠标控制移动的正确实现

针对鼠标跟随+碰撞的场景,推荐用move_and_slide(更适合持续移动,自动处理碰撞响应),或者正确计算motion后用move_and_collide,以下是两种方案:

方案1:用move_and_slide(推荐)

在Sprite的脚本_physics_process函数里写:

func _physics_process(delta):
    # 获取鼠标的世界坐标
    var mouse_world_pos = get_global_mouse_position()
    # 计算朝向鼠标的方向向量(归一化后保证移动速度稳定)
    var move_dir = (mouse_world_pos - global_position).normalized()
    # 设置移动速度(可根据需求调整)
    var move_speed = 250.0
    # 计算最终速度向量
    var velocity = move_dir * move_speed
    # 调用move_and_slide自动处理碰撞
    move_and_slide(velocity)

方案2:用move_and_collide(手动控制位移)

如果一定要用move_and_collide,要正确计算单帧位移:

func _physics_process(delta):
    var mouse_world_pos = get_global_mouse_position()
    var move_dir = (mouse_world_pos - global_position).normalized()
    var move_speed = 250.0
    # 正确计算单帧位移:速度 * 帧时间
    var motion = move_dir * move_speed * delta
    # 执行移动与碰撞
    move_and_collide(motion)

为什么放大碰撞体后瞬移到顶部?

因为你之前的motion值过大,当Sprite冲向碰撞体时,巨大的位移会让引擎认为Sprite直接穿透了碰撞体的侧面,反而触发了顶部的碰撞检测,所以被校正到顶部位置——本质还是错误的位移计算导致的。

额外提示

如果你的需求是让Sprite快速贴近鼠标而非平滑跟随,可以先计算目标位置,再用move_and_collide做带碰撞的瞬移:

func _physics_process(delta):
    var target_pos = get_global_mouse_position()
    # 计算从当前位置到目标位置的位移向量
    var motion = target_pos - global_position
    # 带碰撞的移动到目标位置
    move_and_collide(motion)

这种方式不会出现瞬移,因为引擎会处理碰撞路径,让Sprite停在碰撞体边缘。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 10:22:41