Files
zeling_v2/Docs/Standards/LayerSpec.md

141 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Unity Layer 命名与用途规范
> **版本**1.0
> **创建日期**2026-05
> **适用范围**:项目所有 GameObject 的 Layer 分配
> **关联文档**`Standards/AssetFolderSpec.md`、`Editor/Tools/Physics2DLayerReport.cs`
---
## 目录
1. [概述](#1-概述)
2. [Layer 清单](#2-layer-清单)
3. [Physics 2D 碰撞矩阵](#3-physics-2d-碰撞矩阵)
4. [使用规范](#4-使用规范)
5. [检查与修复工具](#5-检查与修复工具)
---
## 1. 概述
本项目使用固定的 Layer 名称集合来驱动 Physics 2D 碰撞矩阵、伤害判定、视线检测LOS、地面检测等核心系统。所有 Layer 必须在 **Edit → Project Settings → Tags and Layers** 中手动创建,名称必须与本文档一致(大小写敏感)。
> **重要**:代码中通过 `LayerMask.NameToLayer("LayerName")` 引用 Layer若 Layer 不存在将返回 `-1` 并导致逻辑错误。创建场景对象时请优先使用 `BaseGames → Scene → Place` 菜单工具,该工具会自动校验并赋值 Layer。
---
## 2. Layer 清单
### 2.1 玩家相关
| Layer 名称 | 挂载对象 | 用途说明 |
|---|---|---|
| `Player` | 玩家根节点 GameObject | 玩家物理碰撞体(含 Rigidbody2D地面检测、存档点、检查点触发器通过此 Layer 筛选玩家 |
| `PlayerHurtBox` | 玩家子节点 `HurtBox` | 接收伤害的碰撞体isTrigger`EnemyHitBox` / `EnemyProjectile` 命中此 Layer 时对玩家造成伤害 |
| `PlayerHitBox` | 玩家武器 / 技能 HitBox | 发出伤害的碰撞体;命中 `EnemyHurtBox` 时触发对敌人的伤害判定 |
| `PlayerProjectile` | 玩家发射的投射物 | 玩家子弹;不与 `PlayerHurtBox``EnemyProjectile` 碰撞,命中 `EnemyHurtBox``Ground` 时有效 |
### 2.2 敌人相关
| Layer 名称 | 挂载对象 | 用途说明 |
|---|---|---|
| `Enemy` | 敌人根节点 GameObject | 敌人物理碰撞体(含 Rigidbody2D`Ground` 碰撞实现站立 |
| `EnemyHurtBox` | 敌人子节点 `HurtBox` | 接收伤害的碰撞体isTrigger`PlayerHitBox` / `PlayerProjectile` 命中此 Layer 时对敌人造成伤害;`EnemyHitBox` 也可命中此 Layer敌人互伤HitBox 运行时排除自身根节点) |
| `EnemyHitBox` | 敌人武器 HitBox / `LethalTrap` 主体 | 发出伤害的碰撞体;命中 `PlayerHurtBox` 时触发对玩家的伤害判定 |
| `EnemyProjectile` | 敌人发射的投射物 | 敌人子弹;不与 `EnemyHurtBox` 碰撞,命中 `PlayerHurtBox``Ground` 时有效 |
### 2.3 地形相关
| Layer 名称 | 挂载对象 | 用途说明 |
|---|---|---|
| `Ground` | 静态地面、移动平台、Tilemap 地形、障碍物 | 玩家与敌人站立的实体地面;`PlayerMovement``_groundLayer``PlayerWallDetector``_wallLayer`(默认)均包含此 Layer投射物命中后销毁 |
| `Wall` | 墙壁碰撞体(垂直面) | 玩家攀墙检测(`PlayerWallDetector` 默认掩码包含 `Wall``Ground`);若地形使用统一的 Tilemap 则墙壁可合并到 `Ground` Layer |
### 2.4 触发区域
| Layer 名称 | 挂载对象 | 用途说明 |
|---|---|---|
| `TriggerZone` | 存档点(`CheckpointMarker`)、存档台(`SavePoint`)、传送站(`TeleportStation`)、房间过渡(`RoomTransition` / `DoorTransition`)、相机区域(`CameraArea` | 纯触发碰撞体isTrigger不参与物理阻挡统一使用此 Layer 方便在碰撞矩阵中集中管理 |
### 2.5 特殊用途
| Layer 名称 | 挂载对象 | 用途说明 |
|---|---|---|
| `PhantomBody` | 幽灵/幻象角色的实体碰撞体 | `PhantomInteractable` 通过 `other.gameObject.layer == PhantomBody` 判断是否为幻象角色触发交互 |
---
## 3. Physics 2D 碰撞矩阵
以下为项目**期望的碰撞配置**,由 `Physics2DLayerReport` 工具维护与校验。
| Layer A | Layer B | 应碰撞 | 说明 |
|---|---|:---:|---|
| `PlayerHitBox` | `EnemyHurtBox` | ✅ | 玩家攻击伤害敌人 |
| `EnemyHitBox` | `PlayerHurtBox` | ✅ | 敌人攻击伤害玩家 |
| `EnemyHitBox` | `EnemyHurtBox` | ✅ | 敌人可互相伤害HitBox 运行时排除自身根节点) |
| `Player` | `Ground` | ✅ | 玩家站在地面上 |
| `Enemy` | `Ground` | ✅ | 敌人站在地面上 |
| `PlayerProjectile` | `EnemyHurtBox` | ✅ | 玩家投射物伤害敌人 |
| `PlayerProjectile` | `PlayerHurtBox` | ❌ | 玩家投射物不自伤 |
| `PlayerProjectile` | `Ground` | ✅ | 玩家投射物命中地形 |
| `EnemyProjectile` | `PlayerHurtBox` | ✅ | 敌人投射物伤害玩家 |
| `EnemyProjectile` | `EnemyHurtBox` | ❌ | 敌人投射物不自伤 |
| `EnemyProjectile` | `Ground` | ✅ | 敌人投射物命中地形 |
| `PlayerHitBox` | `PlayerHurtBox` | ❌ | 玩家不自伤 |
| `PlayerProjectile` | `EnemyProjectile` | ❌ | 子弹不互相碰撞Clash 系统单独处理) |
> 未在上表中列出的 Layer 对默认继承 Unity 全局设置(默认全部碰撞)。
---
## 4. 使用规范
### 4.1 Layer 赋值方式
- **优先使用 `SceneObjectPlacerTool`**(菜单 `BaseGames → Scene → Place → …`)自动赋值,避免遗漏。
- 手动创建 GameObject 时,在 Inspector 顶部 **Layer** 下拉菜单中选择对应 Layer。
- 代码中引用时,通过 `LayerMask.NameToLayer("LayerName")` 获取整型索引,或通过 `LayerMask.GetMask("LayerA", "LayerB")` 获取掩码值。
```csharp
// 推荐:缓存到字段,避免每帧调用
private int _playerLayer;
void Awake()
{
_playerLayer = LayerMask.NameToLayer("Player");
}
```
### 4.2 子节点继承规则
- 玩家 / 敌人根节点与其 HurtBox、HitBox **必须分别挂不同 Layer**,不可统一使用根节点 Layer。
- `LethalTrap`(陷阱):主体用 `EnemyHitBox`,可弹起的子 `HurtBox``EnemyHurtBox`
- 触发区域对象(存档点等)统一用 `TriggerZone`,不需要额外子节点分层。
### 4.3 禁止事项
- 禁止在代码中硬编码 Layer 整型编号(如 `layer == 8`),必须使用名称转换。
- 禁止直接修改 `ProjectSettings/TagManager.asset` 中的 Layer 顺序(会导致所有已赋值对象 Layer 错乱)。
- 禁止将 `TriggerZone` 对象的 Collider 设置为非 trigger`isTrigger` 必须为 `true`)。
---
## 5. 检查与修复工具
项目提供了 **Physics2DLayerReport** 编辑器工具,位于菜单:
```
BaseGames → Tools → Physics2D Layer Matrix → Check
BaseGames → Tools → Physics2D Layer Matrix → Auto Fix
```
- **Check**:打印当前碰撞矩阵与期望配置的对比报告。
- ✅ 正常
- ❌ 当前配置与期望不符(需修复)
- ⚠ Layer 不存在(需先在 Tags and Layers 中创建)
- **Auto Fix**:自动将所有不符合期望的碰撞对修正为正确值,并持久化到 `ProjectSettings`
> 建议在以下时机运行 **Check**:新人入职初始化环境、合并来自其他分支的 `ProjectSettings` 变更后、新增 Layer 之后。