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

Unity 2D如何获取子弹与敌人精确碰撞点且不产生物理推力

解决方案

方案1:保留OnCollisionEnter2D,通过碰撞层矩阵屏蔽物理交互

这是改动最小、适配性最高的方案:

  • 给子弹、敌人分别设置独立的Unity Layer(比如命名为Bullet、Enemy)
  • 打开Edit > Project Settings > Physics 2D面板,找到Layer Collision Matrix配置项
  • 取消勾选Bullet层和Enemy层对应的交互复选框,两者就不会产生物理碰撞推力,但碰撞检测事件依然会正常触发
  • 原有OnCollisionEnter2D代码无需修改,collision.contacts[0].point仍可返回精确碰撞点

方案2:保留触发器属性,手动计算碰撞接触点

如果不想调整碰撞层配置,可以直接在OnTriggerEnter2D逻辑中计算两个碰撞体的最近接触点:

//Bullet.cs
void OnTriggerEnter2D(PolygonCollider2D enemyCollider)
{
    var enemy = enemyCollider.GetComponent<Enemy>();
    if (enemy != null && enemy.isAlive)
    {
        if (enemy.impactSprite != null)
        {
            Collider2D bulletCollider = GetComponent<Collider2D>();
            // 计算两个碰撞体之间的最近点,即实际碰撞接触位置
            Vector2 contactPoint = Physics2D.Distance(bulletCollider, enemyCollider).closestPoint;
            Instantiate(enemy.impactSprite, contactPoint, transform.rotation);
        }
        enemy.TakeDamage(damage);
        Destroy(gameObject);
        return;
    }
}

该方案不需要修改碰撞体的触发器属性,完全无物理交互,仅增加极微的计算开销,适配所有子弹形状。

方案3:固定偏移修正(仅适合规则子弹)

如果你的子弹是固定朝向飞行的规则形状,可以直接修正特效生成的位置偏移:

//Bullet.cs
void OnTriggerEnter2D(PolygonCollider2D hitInfo)
{
    var enemy = hitInfo.GetComponent<Enemy>();
    if (enemy != null && enemy.isAlive)
    {
        if (enemy.impactSprite != null)
        {
            // 按子弹飞行方向偏移半个子弹宽度,25像素转世界单位的计算公式:像素值 / 项目Pixels Per Unit(默认100)
            float offset = 25f / 100f;
            Vector3 spawnPos = transform.position + transform.right * offset;
            Instantiate(enemy.impactSprite, spawnPos, transform.rotation);
        }
        enemy.TakeDamage(damage);
        Destroy(gameObject);
        return;
    }
}

该方案零额外开销,仅适合固定朝向的规则子弹,不支持旋转、不规则形状的子弹。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 13:21:01