You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何阻止两个Dynamic模式Rigidbody2D对象碰撞时互相推挤?

解决Dynamic Rigidbody2D互相推挤的问题

以下是几种可行的解决方案,根据你的需求选择最适合的:

方案1:通过碰撞层矩阵过滤物理交互

这是最直接高效的方法,完全避免玩家与敌人之间的物理推挤:

  • 给玩家、敌人、战斗层对象分别创建独立的Layer(比如PlayerEnemyCombat)。
  • 打开Edit > Project Settings > Physics2D,找到Layer Collision Matrix
    • 取消Player层和Enemy层之间的「Physics」勾选(如果需要检测两者接触,保留「Trigger」勾选即可)。这样两者碰撞时不会产生任何物理冲量,自然不会互相推挤。
    • 确保PlayerEnemy层与Combat层的「Physics」勾选保持开启,让战斗层对象击中时能正常传递力。
  • 如果需要检测玩家和敌人的接触(比如进入攻击范围),可以将其中一个Collider设为Trigger,用OnTriggerEnter2D处理接触逻辑,既无推挤又能检测接触。

方案2:脚本控制刚体速度,抵消推挤力

如果不想修改碰撞矩阵,可通过脚本在碰撞时恢复刚体原有速度:
给玩家和敌人都添加以下脚本,并设置对应的Tag(Player/Enemy):

using UnityEngine;

public class PreventCrossPush : MonoBehaviour
{
    private Rigidbody2D _rb;
    private Vector2 _lastValidVelocity;

    void Awake()
    {
        _rb = GetComponent<Rigidbody2D>();
    }

    void FixedUpdate()
    {
        // 每一帧记录当前速度,用于碰撞后恢复
        _lastValidVelocity = _rb.velocity;
    }

    void OnCollisionStay2D(Collision2D other)
    {
        // 只处理玩家与敌人之间的碰撞
        if (other.gameObject.CompareTag("Player") || other.gameObject.CompareTag("Enemy"))
        {
            // 恢复碰撞前的速度,抵消推挤产生的力
            _rb.velocity = _lastValidVelocity;
        }
    }
}
  • 原理是在物理更新前记录刚体速度,当和玩家/敌人碰撞时,强制重置回碰撞前的状态,避免互相推挤导致的位移。
  • 战斗层对象因Tag不符,碰撞时不会触发速度重置,能正常推动目标。

方案3:精准抵消非战斗层的碰撞冲量

更精细的控制方式,直接在碰撞时过滤非战斗层的力:

using UnityEngine;

public class FilterCombatForce : MonoBehaviour
{
    private Rigidbody2D _rb;
    private int _combatLayer;

    void Awake()
    {
        _rb = GetComponent<Rigidbody2D>();
        _combatLayer = LayerMask.NameToLayer("Combat");
    }

    void OnCollisionEnter2D(Collision2D other)
    {
        // 仅允许战斗层对象传递力,其他碰撞直接清除冲量
        if (other.gameObject.layer != _combatLayer)
        {
            // 抵消碰撞产生的冲量,也可直接重置速度
            _rb.AddForce(-other.impulse / Time.fixedDeltaTime, ForceMode2D.Impulse);
        }
    }
}
  • 这个方法直接针对碰撞冲量进行抵消,只保留战斗层对象的受力效果,适合需要保留部分物理交互但过滤推挤的场景。

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

火山引擎 最新活动