# 57 · 物理层矩阵(Physics Layer Matrix) > **命名空间** `BaseGames.Physics`(配置层) > **所属文档集** [← 返回索引](./README.md) · [总览](./00_Overview.md) > **关联** 04_CombatSystem(HitBox/HurtBox)· 06_EnemySystem · 13_ProjectileSystem · 24_GroundDetectionSystem · 40_LiquidSwimSystem --- ## 目录 1. [Layer 定义总表](#1-layer-定义总表) 2. [碰撞矩阵(Layer Collision Matrix)](#2-碰撞矩阵layer-collision-matrix) 3. [Physics Material 目录](#3-physics-material-目录) 4. [Rigidbody2D 使用规范](#4-rigidbody2d-使用规范) 5. [Trigger vs Collider 使用规范](#5-trigger-vs-collider-使用规范) 6. [Layer 相关代码规范](#6-layer-相关代码规范) 7. [常见错误与排查](#7-常见错误与排查) --- ## 1. Layer 定义总表 Unity 物理层(Layer 0~31),固定分配,不允许随意挪用: | Layer ID | 名称 | 用途 | |---------|------|------| | 0 | `Default` | 场景中无特殊需求的静态物件(不参与物理计算的装饰物)| | 1 | `TransparentFX` | Unity 内置,粒子特效(不参与碰撞)| | 2 | `Ignore Raycast` | Unity 内置,不参与任何 Raycast | | 3 | `(保留)` | — | | 4 | `Water` | Unity 内置(本项目不使用,用 LiquidZone 代替)| | 5 | `UI` | Unity 内置,UI 层 | | 6 | `(保留)` | — | | 7 | `(保留)` | — | | **8** | `Ground` | 地面、平台(玩家/敌人站立的实体碰撞)| | **9** | `OneWayPlatform` | 单向平台(可从下方穿越,从上方落下后站立)| | **10** | `Wall` | 垂直墙壁(可抓附的墙体)| | **11** | `Hazard` | 伤害区域(荆棘/熔岩地面/毒液,无碰撞体阻挡,仅触发 Trigger)| | **12** | `Player` | 玩家 Prefab 主体 Collider | | **13** | `PlayerHitBox` | 玩家攻击判定区(HitBox)| | **14** | `PlayerHurtBox` | 玩家受击区(HurtBox)| | **15** | `Enemy` | 敌人主体 Collider | | **16** | `EnemyHitBox` | 敌人攻击判定区(HitBox)| | **17** | `EnemyHurtBox` | 敌人受击区(HurtBox)| | **18** | `Projectile` | 弹射物(玩家射出的子弹、Boss 弹幕)| | **19** | `EnemyProjectile` | 敌人弹射物(与 Projectile 分层,防止玩家弹射物误伤自己)| | **20** | `ParryTarget` | 可弹反的弹射物(HurtBox 对 Parry 检测,见 05_ParrySystem)| | **21** | `Interactable` | 可交互物件触发区(IInteractable Trigger)| | **22** | `LiquidZone` | 液态区域(Trigger,见 40_LiquidSwimSystem)| | **23** | `AbilityGate` | 能力门触发区(Trigger,见 14_ProgressionSystem)| | **24** | `Pickup` | 掉落物/收集品(Trigger,靠近自动吸附)| | **25** | `Room` | 房间边界触发区(Trigger,触发场景加载/卸载)| | **26** | `CameraZone` | Cinemachine 约束区域(Trigger,不参与物理)| | **27** | `VFX` | VFX 粒子(仅视觉,不参与碰撞)| | **28** | `NavMesh` | 寻路 Agent(PathBerserker2d 专属,不与普通物理交互)| | **29** | `MagicWall` | 魔法障壁(`Ghost` 层忽略此层,实现太虚斩/地行术穿越)| | **30** | `Ghost` | 玩家施放太虚斩/地行术激活期间切换到此层;忽略 `MagicWall` 碰撞 | | **31** | `PhantomBody` | 残阴术灵体 Rigidbody2D;可触发 `PhantomInteractable`,忽略其余实体碰撞 | --- ## 2. 碰撞矩阵(Layer Collision Matrix) **✅ = 相互检测碰撞 / Trigger 触发** | **─ = 忽略(不检测)** > 仅列出有意义的组合,其余均为 `─`。 | | Ground | OWPlatform | Wall | Hazard | Player | PlayerHB | PlayerHurtB | Enemy | EnemyHB | EnemyHurtB | Projectile | EnemyProj | ParryTarget | Interactable | LiquidZone | Pickup | Room | |--|--------|-----------|------|--------|--------|---------|------------|-------|---------|-----------|-----------|----------|------------|-------------|-----------|--------|------| | **Ground** | ─ | ─ | ─ | ─ | ✅ | ─ | ─ | ✅ | ─ | ─ | ✅ | ✅ | ─ | ─ | ─ | ─ | ─ | | **OWPlatform** | ─ | ─ | ─ | ─ | ✅ | ─ | ─ | ✅ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | | **Wall** | ─ | ─ | ─ | ─ | ✅ | ─ | ─ | ✅ | ─ | ─ | ✅ | ✅ | ─ | ─ | ─ | ─ | ─ | | **Hazard** | ─ | ─ | ─ | ─ | ✅(T) | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | | **Player** | ✅ | ✅ | ✅ | ✅(T) | ─ | ─ | ─ | ─ | ✅(T) | ─ | ─ | ✅(T) | ─ | ✅(T) | ✅(T) | ✅(T) | ✅(T) | | **PlayerHitBox** | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ✅(T) | ─ | ─ | ─ | ─ | ─ | ─ | ─ | | **PlayerHurtBox** | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ✅(T) | ─ | ─ | ✅(T) | ✅(T) | ─ | ─ | ─ | ─ | | **Enemy** | ✅ | ✅ | ✅ | ─ | ─ | ✅(T) | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | | **EnemyHitBox** | ─ | ─ | ─ | ─ | ─ | ─ | ✅(T) | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | | **EnemyHurtBox** | ─ | ─ | ─ | ─ | ─ | ✅(T) | ─ | ─ | ─ | ─ | ✅(T) | ─ | ─ | ─ | ─ | ─ | ─ | | **Projectile** | ✅ | ─ | ✅ | ─ | ─ | ─ | ✅(T) | ─ | ─ | ✅(T) | ─ | ─ | ─ | ─ | ─ | ─ | ─ | | **EnemyProjectile** | ✅ | ─ | ✅ | ─ | ✅(T) | ─ | ✅(T) | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | | **ParryTarget** | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | ─ | > (T) = 仅 Trigger 检测(OnTriggerEnter2D / OnTriggerStay2D),不产生物理推力 ### 新增层补充矩阵(Ghost / MagicWall / PhantomBody) | | Ground | OWPlatform | Wall | MagicWall | Player | Enemy | Interactable | PhantomInteractable | |--|--------|-----------|------|-----------|--------|-------|-------------|--------------------| | **Ghost** | ✅ | ✅ | ✅ | ❌ 忽略 | ─ | ─ | ✅(T) | ✅(T) | | **MagicWall** | ─ | ─ | ─ | ─ | ✅ | ✅ | ─ | ─ | | **PhantomBody** | ❌ 忽略 | ❌ 忽略 | ❌ 忽略 | ❌ 忽略 | ─ | ─ | ─ | ✅(T) | > - **Ghost**:玩家变换为幽灵层后,与 `MagicWall` 无碰撞(穿越),但仍与地面/墙壁碰撞(地行术需要站在地面上遁行)。 > - **PhantomBody**:残阴术灵体完全忽略地面/墙壁,仅 Trigger 触发 `PhantomInteractable`(`Interactable` 子层)。 > - `SoftTerrain`(松软地面)**不需要独立物理层**:使用 `Ground` 层,`GroundDiveState` 通过 `Physics2D.OverlapPoint()` 的返回值检查是否挂载 `SoftTerrain` 组件来判断地形类型。 ### 矩阵关键设计决策 | 决策 | 原因 | |------|------| | `Enemy` 不与 `EnemyProjectile` 碰撞 | 防止 Boss 弹幕打到自己身上 | | `Projectile` 不与 `Enemy` 碰撞(走 EnemyHurtBox)| 弹射物不推动敌人刚体,只通过 HurtBox 触发伤害 | | `PlayerHitBox` 不与 `Ground/Wall` 碰撞 | 防止近地攻击被地面碰撞遮挡 | | `Hazard` 只触发 `Player`,不触发 `Enemy` | 敌人在自己的陷阱中不受伤 | | `ParryTarget` 不与任何层碰撞 | 弹反检测由 `ParrySystem` 的 `OverlapCircle` 主动查询,无需被动碰撞 | --- ## 3. Physics Material 目录 存放路径:`Assets/Physics/Materials/` | 资产名 | Friction | Bounciness | 使用对象 | |--------|---------|-----------|---------| | `PhysMat_Ground` | 0.4 | 0.0 | 地面碰撞体(普通地板)| | `PhysMat_Ice` | 0.02 | 0.0 | 冰面地块(低摩擦)| | `PhysMat_Bounce` | 0.2 | 0.8 | 弹跳蘑菇/弹射台 | | `PhysMat_Player` | 0.0 | 0.0 | 玩家 Rigidbody2D Collider(零摩擦防止卡墙)| | `PhysMat_Enemy` | 0.3 | 0.0 | 敌人 Rigidbody2D Collider | | `PhysMat_Projectile` | 0.0 | 0.0 | 弹射物(与地面/墙壁碰撞时不反弹,由代码控制反弹逻辑)| | `PhysMat_Liquid` | 0.0 | 0.0 | 液态区域边界(仅 Trigger,但 PhysMat 仍设为零摩擦)| ### 摩擦力处理原则 - **玩家碰撞体摩擦力始终为 0**——移动完全由 `PlayerMovement` 的速度控制,不依赖物理摩擦 - 坡面行走不依赖摩擦力,而是使用地面法线修正移动方向(见 24_GroundDetectionSystem.md) - 弹跳效果不依赖 `Bounciness` 物理材质,而是在 `OnCollisionEnter2D` 中代码施加冲量(更可控) --- ## 4. Rigidbody2D 使用规范 | 对象类型 | Body Type | Interpolation | Collision Detection | Constraints | |---------|-----------|--------------|--------------------|----| | **玩家** | Dynamic | Interpolate | Continuous | FreezeRotation Z | | **跟随平台(可移动地块)**| Kinematic | Interpolate | Continuous | — | | **普通敌人(地面)** | Dynamic | Interpolate | Discrete | FreezeRotation Z | | **飞行敌人** | Dynamic | Interpolate | Discrete | FreezeRotation Z | | **弹射物** | Dynamic | None | Continuous | FreezeRotation Z | | **可破坏物件** | Dynamic(激活前 Kinematic)| None | Discrete | — | | **触发区域(Hazard/LiquidZone 等)** | 无 Rigidbody2D | — | — | — | **禁止行为**: - ❌ 不在 `Update()` 中直接修改 `transform.position`(会绕过物理,用 `Rigidbody2D.MovePosition`) - ❌ 不设置 `Rigidbody2D.velocity` 直接赋值(除非做瞬间冲刺,否则用 `AddForce`) - ❌ 不在运行时频繁切换 Body Type(`Dynamic ↔ Kinematic` 切换有性能开销) --- ## 5. Trigger vs Collider 使用规范 | 用途 | 使用 Collider | 使用 Trigger | |------|-------------|------------| | 角色站立在地面上 | ✅ Collider | ❌ | | HitBox / HurtBox 伤害检测 | ❌ | ✅ Trigger | | 危险区域(荆棘)伤害 | ❌ | ✅ Trigger | | 液态区域检测 | ❌ | ✅ Trigger | | 交互提示范围(InteractionPrompt)| ❌ | ✅ Trigger | | 房间边界(加载/卸载触发)| ❌ | ✅ Trigger | | 镜头约束区域(Cinemachine ConfinerBound)| ✅ Collider(设为 Trigger)| 二者并存(见 Cinemachine 文档)| | 弹射物与墙面碰撞(需反弹计算)| ✅ Collider | ❌ | | 弹射物与 HurtBox | ❌ | ✅ Trigger | **混合使用**(同一 Collider2D 同时作为 Collider 和 Trigger): - ❌ **禁止**——同一 Collider 不能同时是 Collider 和 Trigger,语义混乱 - 需要两种功能时,在同一 GameObject 上添加两个 Collider2D 组件 --- ## 6. Layer 相关代码规范 ### 6.1 使用 LayerMask 常量,禁止硬编码数字 ```csharp // ✅ 正确 private static readonly int LayerGround = LayerMask.NameToLayer("Ground"); private static readonly LayerMask MaskGround = LayerMask.GetMask("Ground", "OneWayPlatform"); // ❌ 禁止 int layer = 8; // 硬编码 Layer ID ``` ### 6.2 统一 LayerMask 常量类 ```csharp // Assets/Scripts/Core/Physics/Layers.cs public static class Layers { public static readonly int Ground = LayerMask.NameToLayer("Ground"); public static readonly int OneWayPlatform = LayerMask.NameToLayer("OneWayPlatform"); public static readonly int Wall = LayerMask.NameToLayer("Wall"); public static readonly int Player = LayerMask.NameToLayer("Player"); public static readonly int PlayerHitBox = LayerMask.NameToLayer("PlayerHitBox"); public static readonly int PlayerHurtBox = LayerMask.NameToLayer("PlayerHurtBox"); public static readonly int Enemy = LayerMask.NameToLayer("Enemy"); public static readonly int EnemyHitBox = LayerMask.NameToLayer("EnemyHitBox"); public static readonly int EnemyHurtBox = LayerMask.NameToLayer("EnemyHurtBox"); public static readonly int Projectile = LayerMask.NameToLayer("Projectile"); public static readonly int EnemyProjectile = LayerMask.NameToLayer("EnemyProjectile"); public static readonly int Hazard = LayerMask.NameToLayer("Hazard"); public static readonly int LiquidZone = LayerMask.NameToLayer("LiquidZone"); public static readonly int Pickup = LayerMask.NameToLayer("Pickup"); public static readonly int Room = LayerMask.NameToLayer("Room"); // 技能专属层 public static readonly int Ghost = LayerMask.NameToLayer("Ghost"); // 太虚斩/地行术幽灵层 public static readonly int PhantomBody = LayerMask.NameToLayer("PhantomBody"); // 残阴术灵体层 public static readonly int MagicWall = LayerMask.NameToLayer("MagicWall"); // 魔法障壁(Ghost 穿越) // 复合 Mask(常用组合) public static readonly LayerMask MaskSolidGround = LayerMask.GetMask("Ground", "OneWayPlatform"); public static readonly LayerMask MaskWallAndGround = LayerMask.GetMask("Ground", "OneWayPlatform", "Wall"); public static readonly LayerMask MaskAllHurtBox = LayerMask.GetMask("PlayerHurtBox", "EnemyHurtBox"); public static readonly LayerMask MaskEnemy = LayerMask.GetMask("Enemy", "EnemyHurtBox"); // Ghost 状态时的地面检测(排除 MagicWall,但保留普通地面) public static readonly LayerMask MaskGhostGround = LayerMask.GetMask("Ground", "OneWayPlatform"); } ``` ### 6.3 Layer 设置检查器(CI 集成) 在 `Assets/Tests/EditMode/PhysicsLayerTests.cs` 中验证: - 所有 Layer 名称正确注册 - Collision Matrix 中的关键对/忽略关系与本文档一致 - 玩家 Prefab 使用正确的 Layer --- ## 7. 常见错误与排查 | 症状 | 原因 | 修复 | |------|------|------| | 玩家无法站在地面上 | Player 与 Ground 的碰撞被关闭 | 检查 Collision Matrix | | 攻击打不到敌人 | PlayerHitBox 与 EnemyHurtBox 碰撞关系未启用 | 勾选矩阵对应格 | | 弹射物穿透地面 | Projectile 的 Collision Detection 设为 Discrete | 改为 Continuous | | 危险区域不造成伤害 | Hazard 碰撞体忘记勾选 Is Trigger | 勾选 Is Trigger | | 敌人被自己的弹幕打到 | Enemy 与 EnemyProjectile 未忽略 | 检查矩阵,确认忽略 | | 近地面攻击被地面碰撞打断 | PlayerHitBox 与 Ground 未忽略 | 确认矩阵忽略该组合 | | 单向平台两侧可以穿过 | OneWayPlatform 应用了标准碰撞 | 使用 `PlatformEffector2D` 组件 | --- *本文档版本 1.0 · 2026-04 · 关联 04_CombatSystem / 13_ProjectileSystem / 24_GroundDetectionSystem*