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

Unity 2D空对象collider设置问题:如何实现玩家可穿、敌人不可穿?

问题原因

你当前的Collider应该是勾选了Is Trigger选项,触发态的碰撞器只会触发碰撞事件,不会产生物理阻挡效果,所以玩家和敌人都可以自由穿过。

两种实现方案

方案1:用层碰撞矩阵实现(推荐,性能最优,无需额外逻辑)

  • 新建三个层级:Player、Enemy、SpecialObstacle,分别将玩家对象归属到Player层、敌人归属到Enemy层、你的空对象归属到SpecialObstacle层
  • 打开顶部菜单 编辑 > 项目设置 > 物理(3D项目)/ 编辑 > 项目设置 > 物理2D(2D项目),找到层碰撞矩阵配置项
  • 取消SpecialObstacle和Player交叉选项的勾选,保留SpecialObstacle和Enemy交叉选项的勾选,其余原有碰撞规则无需修改
  • 回到空对象的Collider组件配置,取消Is Trigger的勾选,此时物理引擎会自动按层规则处理碰撞:玩家和该对象无碰撞判定可直接穿过,敌人和该对象有碰撞判定会被阻挡
  • 如果需要保留原有的碰撞触发事件逻辑,可以给空对象额外新增一个Collider组件,第二个Collider勾选Is Trigger,并在层碰撞矩阵中设置该触发层可同时和Player、Enemy碰撞,原有触发逻辑不受影响

方案2:代码判断实现(适合不想调整层级的场景)

  • 保留空对象Collider的Is Trigger勾选状态
  • 给敌人对象提前设置Enemy标签,给空对象挂载以下逻辑脚本即可:
using UnityEngine;

public class EnemyOnlyObstacle : MonoBehaviour
{
    // 3D项目用OnTriggerStay
    private void OnTriggerStay(Collider other)
    {
        if (other.CompareTag("Enemy"))
        {
            // 计算反方向推力阻挡敌人
            Vector3 repelDir = other.transform.position - transform.position;
            repelDir.y = 0; // 2D项目改为repelDir.z = 0
            other.transform.position += repelDir.normalized * Time.deltaTime * 5f;
        }
    }

    // 2D项目替换为下面的方法即可
    // private void OnTriggerStay2D(Collider2D other)
    // {
    //     if (other.CompareTag("Enemy"))
    //     {
    //         Vector2 repelDir = other.transform.position - transform.position;
    //         other.transform.position += (Vector3)repelDir.normalized * Time.deltaTime * 5f;
    //     }
    // }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 00:54:04