chore: initial commit

This commit is contained in:
2026-05-08 11:04:00 +08:00
commit f55d2a57c3
6278 changed files with 866081 additions and 0 deletions

View File

@@ -0,0 +1,244 @@
# 57 · 物理层矩阵Physics Layer Matrix
> **命名空间** `BaseGames.Physics`(配置层)
> **所属文档集** [← 返回索引](./README.md) · [总览](./00_Overview.md)
> **关联** 04_CombatSystemHitBox/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` | 寻路 AgentPathBerserker2d 专属,不与普通物理交互)|
| **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*