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

Unity中Rigidbody2D物体穿透碰撞体时出现抖动问题

球体穿透Block时卡顿问题解决

场景设置

  • 球体对象:
    • 挂载CircleCollider2D:使用无摩擦、反弹系数为1的材质,非触发器
    • 挂载Rigidbody2D:无重力、有质量、开启Continuous碰撞检测、Interpolate设为Interpolate
    • 附加脚本:
Rigidbody2D rb;
private void Awake() {
    rb = GetComponent<Rigidbody2D>();
}
Vector2 lastVelocity;
private void FixedUpdate() {
    lastVelocity = rb.velocity;
}

private void OnCollisionEnter2D(Collision2D other) {
    if (other.gameObject.tag == "Block" && isPiercing) {
        rb.velocity = lastVelocity;
    }
}
  • Block对象:仅带有BoxCollider2D(非触发器)

预期与实际现象

  • 预期:isPiercing属性启用时,球体穿透Block;未启用时正常反弹(此功能正常)
  • 实际:球体接触Block时出现抖动、路径轻微回退,虽能穿透但有明显卡顿感

疑问

是否需要在碰撞时将球体沿路径前移,抵消即将发生的反弹效果?

解决方案

你的思路是对的,卡顿根源是物理引擎已经完成了碰撞反弹的位置修正,仅重置velocity只能恢复速度,但位置已经被引擎往回推了,所以会出现抖动回退。下面给两种直接可行的解决办法:

方法1:同时修正位置与速度

在碰撞触发时,除了重置速度,还要将球体沿运动方向前移,抵消引擎的位置回退。可以利用碰撞接触点的信息计算移动距离:

private void OnCollisionEnter2D(Collision2D other) {
    if (other.gameObject.tag == "Block" && isPiercing) {
        // 恢复碰撞前的速度
        rb.velocity = lastVelocity;
        // 计算需要移动的距离:球体半径 + 碰撞接触的偏移量,确保完全穿过Block
        CircleCollider2D sphereCollider = GetComponent<CircleCollider2D>();
        float pushDistance = sphereCollider.radius + Mathf.Abs(other.contacts[0].separation);
        // 沿运动方向移动球体
        transform.Translate(lastVelocity.normalized * pushDistance);
    }
}

如果存在多个接触点,可根据实际情况选择最合理的接触点计算,单个Block场景下取第一个接触点即可。

方法2:临时禁用碰撞器(更简洁)

开启穿透时,碰撞瞬间临时关闭球体的碰撞器,待球体完全穿过Block后再重新启用。注意调整延迟时间,适配球体速度与Block厚度:

private void OnCollisionEnter2D(Collision2D other) {
    if (other.gameObject.tag == "Block" && isPiercing) {
        // 关闭碰撞器,让球体直接穿过
        GetComponent<CircleCollider2D>().enabled = false;
        // 延迟开启碰撞器,时间根据球体速度和Block厚度调整
        Invoke(nameof(EnableCollider), 0.02f);
        // 保持原有运动速度
        rb.velocity = lastVelocity;
    }
}

private void EnableCollider() {
    GetComponent<CircleCollider2D>().enabled = true;
}

这种方法实现简单,适合球体运动速度相对稳定的场景。

额外优化提示

  • 若球体移动速度极快,可将Rigidbody2D的碰撞检测模式改为Continuous Dynamic,进一步减少穿透检测的延迟。
  • 可在FixedUpdate中提前判断isPiercing状态,若开启则直接跳过碰撞相关的逻辑处理,但效果不如上述两种方法直接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 13:36:05