diff --git a/.claude/agent-memory/game-dev/MEMORY.md b/.claude/agent-memory/game-dev/MEMORY.md new file mode 100644 index 0000000..177b2a6 --- /dev/null +++ b/.claude/agent-memory/game-dev/MEMORY.md @@ -0,0 +1 @@ +- [Level Builder Tool](level-builder-tool.md) — 白模关卡自动生成 Python 脚本(tools/level-builder/,265 Actor 解析验证通过) diff --git a/.claude/agent-memory/game-dev/level-builder-tool.md b/.claude/agent-memory/game-dev/level-builder-tool.md new file mode 100644 index 0000000..3d5dc57 --- /dev/null +++ b/.claude/agent-memory/game-dev/level-builder-tool.md @@ -0,0 +1,44 @@ +--- +name: level-builder-tool +description: 白模关卡自动生成 Python 脚本工具,位于 tools/level-builder/ +metadata: + type: project +--- + +# Level Builder 工具 + +## 位置 +`tools/level-builder/` + +## 功能 +两阶段流水线:解析搭建指南 Markdown → JSON → UE5 Actor + +## 使用方式 +```bash +# 解析 +python tools/level-builder/main.py parse -i docs/technical/关卡-v01-搭建指南.md -o output/level_v01.json + +# 验证 +python tools/level-builder/main.py validate -i output/level_v01.json + +# 报告 +python tools/level-builder/main.py report -i output/level_v01.json -o output/搭建报告.md +``` + +## UE5 构建 +在 UE5 编辑器 Python 控制台中: +```python +exec(open(r"tools/level-builder/main.py").read()) +# 然后 main(["build", "-i", "output/level_v01.json"]) +``` + +**Why:** 替代手动白模关卡搭建流程,从策划执行案/搭建指南自动生成关卡 +**How to apply:** 收到白模搭建任务时,优先运行此工具而非手动操作 + +## 依赖 +- UE5 PythonScriptPlugin 已在 .uproject 中启用 +- 37 种 BSP 资产映射(config/asset_mapping.py) +- 当前解析搭建指南(parsers/build_guide_parser.py),未来扩展执行案解析器 + +## 数据 +- v0.1 解析结果:265 个 Actor(STR:123, PROP:53, BND:61, INTR:10, COLL:9, LGT:8, PLAY:1) diff --git a/.claude/agents/game-designer.md b/.claude/agents/game-designer.md index 95beb1d..6805ac3 100644 --- a/.claude/agents/game-designer.md +++ b/.claude/agents/game-designer.md @@ -35,7 +35,7 @@ memory: project ``` 概念草案(灵魂)→ 系统设计案(骨架)→ 执行案(血肉) - concept.md .md -execution.md + 概念草案.md <系统名>.md <系统名>-执行案.md "这个游戏是什么" "有哪些系统,如何关联" "程序实现的交互规则" ``` @@ -43,29 +43,29 @@ memory: project ``` docs/design/ - concept.md # 概念草案(原型阶段开始后冻结) + 概念草案.md # 概念草案(原型阶段开始后冻结) prototype/ # 原型阶段产出 README.md # 设计文档索引 - .md # 系统设计案 - -execution.md # 执行案 - scene-v-.md # 场景设计(索引中链接) - brainstorm-YYYY-MM-DD-.md # 头脑风暴记录 + <系统名>.md # 系统设计案 + <系统名>-执行案.md # 执行案 + 场景-v-<名称>.md # 场景设计(索引中链接) + 头脑风暴-YYYY-MM-DD-<主题>.md # 头脑风暴记录 production/ # 批量生产阶段(从 prototype/ 复制) GameConfig/ # 数值配置表 - .csv / .json + <名称>.csv / <名称>.json ``` ### 文件命名规范 | 文档类型 | 格式 | 示例 | |---------|------|------| -| 头脑风暴 | `brainstorm-YYYY-MM-DD-.md` | `brainstorm-2026-06-01-vision-pillars.md` | -| 系统设计案 | `.md` | `interaction-system.md` | -| 执行案 | `-execution.md` | `player-controller-execution.md` | -| 场景设计 | `scene-v-.md` | `scene-v01-suburban.md` | -| 关卡执行案 | `level-v--execution.md` | `level-v01-suburban-execution.md` | -| 配置表 | `.csv` 或 `.json` | `marble-params.csv` | +| 头脑风暴 | `头脑风暴-YYYY-MM-DD-<主题>.md` | `头脑风暴-2026-06-01-愿景支柱.md` | +| 系统设计案 | `<系统名>.md` | `交互系统.md` | +| 执行案 | `<系统名>-执行案.md` | `玩家控制器-执行案.md` | +| 场景设计 | `场景-v-<名称>.md` | `场景-v01-城郊小街.md` | +| 关卡执行案 | `关卡-v-<名称>-执行案.md` | `关卡-v01-城郊小街-执行案.md` | +| 配置表 | `<名称>.csv` 或 `<名称>.json` | `弹珠参数.csv` | --- @@ -83,10 +83,10 @@ GameConfig/ # 数值配置表 2. **一次一个问题** — 使用 AskUserQuestion 提供选项或开放提问。绝不一次性抛出所有问题。 3. **要具体场景** — 如果回答模糊,问"你能描述一下那个时刻的画面吗?" 4. **及时总结共识** — 每个子话题讨论后,总结并确认双方理解一致。 -5. **记录结果** — 写入 `brainstorm-YYYY-MM-DD-.md`。 +5. **记录结果** — 写入 `头脑风暴-YYYY-MM-DD-<主题>.md`。 ### 头脑风暴记录 -- 位置:`docs/design//brainstorm-YYYY-MM-DD-.md` +- 位置:`docs/design//头脑风暴-YYYY-MM-DD-<主题>.md` - 性质:非正式会议笔记,无固定格式,记录要点和共识。 - 目的:下次会话阅读,避免重复讨论。 @@ -113,7 +113,7 @@ GameConfig/ # 数值配置表 ## 阶段特定行为 ### 草案阶段 -- 产出 `docs/design/concept.md`,包含 7 个必填字段: +- 产出 `docs/design/概念草案.md`,包含 7 个必填字段: 1. 一句话描述 2. 玩家核心游玩内容与感受 3. 核心受众画像 @@ -122,8 +122,8 @@ GameConfig/ # 数值配置表 6. 市场定位与三大卖点 7. 参考 - 极轻量;可以反复推翻。 -- **用户确认并进入原型阶段后:concept.md 冻结。** 不再修改。 -- 偏离概念的内容应记录在系统设计案中并说明原因,不修改 concept.md。 +- **用户确认并进入原型阶段后:概念草案.md 冻结。** 不再修改。 +- 偏离概念的内容应记录在系统设计案中并说明原因,不修改概念草案.md。 ### 原型阶段 - 灵活性:核心行为必须完整,非核心可略过。 @@ -343,8 +343,7 @@ GameConfig/ # 数值配置表 ## 阅读参考文档 开始工作前,阅读相关参考文档: -- `.claude/refs/development-workflow.md` — 流水线定义、阶段划分、质量标准 -- `docs/design/concept.md` — 已冻结的概念草案(只读参考) +- `docs/design/概念草案.md` — 已冻结的概念草案(只读参考) - 已有的设计文档 `docs/design//` — 产出新文档前了解当前状态 - 项目管理工具 — 查看分配给你的任务和流水线状态 @@ -361,7 +360,7 @@ GameConfig/ # 数值配置表 ### 产出时机 关卡执行案在 **③执行案阶段** 产出,与系统执行案同步。产出前先阅读: -- 对应的场景设计案 `scene-v-.md`(氛围愿景) +- 对应的场景设计案 `场景-v-<名称>.md`(氛围愿景) - `.claude/refs/level-execution-template.md`(文档模板) - `.claude/refs/blockout-asset-reference.md`(BSP 资产参考卡) @@ -369,13 +368,13 @@ GameConfig/ # 数值配置表 1. **混合坐标体系**:区域用场景绝对坐标(原点在西南角),区域内物件用相对偏移坐标 2. **BSP 资产建议是方向性指引**:引用资产类别名和组合方式(如 "Wall_400x300 × 2"),不写文件路径 -3. **交叉引用**:交互物引用 `interaction-system-execution.md` 编号,收集品引用 `collection-system-execution.md` 编号 +3. **交叉引用**:交互物引用 `交互系统-执行案.md` 编号,收集品引用 `收集系统-执行案.md` 编号 4. **不越界**:不写引擎组件名、文件路径、Blueprint 类名 5. **标识色**:每个区域指定 `MI_Dev<颜色>` 标识色材质,供白模阶段区分 ### 完整规范 -参见 `docs/design/prototype/level-design-workflow.md`。 +参见 `docs/design/prototype/关卡设计工作流.md`。 --- diff --git a/.claude/agents/game-dev.md b/.claude/agents/game-dev.md index d413ea8..26fdd33 100644 --- a/.claude/agents/game-dev.md +++ b/.claude/agents/game-dev.md @@ -20,7 +20,7 @@ memory: project | 文档 | 路径 | 用途 | |------|------|------| -| 技术设计方案 | `docs/technical/-tech.md` | 回应执行文档每条规则的实现方案 | +| 技术设计方案 | `docs/technical/<系统名>-技术方案.md` | 回应执行文档每条规则的实现方案 | | C++ 源码 | `Source/` | 引擎级系统、性能关键路径 | | 蓝图资产 | `Content/Blueprints/` | 游戏逻辑、UI、交互 | | DataAsset | `Content/Data/` | 数据驱动的配置资产 | @@ -88,10 +88,10 @@ memory: project ``` **必须按序阅读的输入**: -1. 执行文档 (`docs/design//-execution.md`) — 行为规则细节 -2. 系统设计文档 (`docs/design//.md`) — 全局上下文 +1. 执行文档 (`docs/design//<系统名>-执行案.md`) — 行为规则细节 +2. 系统设计文档 (`docs/design//<系统名>.md`) — 全局上下文 3. 配置表 (`GameConfig/`) — 可调参数 -4. 概念文档 (`docs/design/concept.md`) — 方向参考(需要理解设计意图时查阅) +4. 概念文档 (`docs/design/概念草案.md`) — 方向参考(需要理解设计意图时查阅) **技术设计文档**:按 `.claude/skills/requirements-analysis/` 中定义的需求分析 skill 产出。 @@ -124,14 +124,14 @@ memory: project 当版本开发涉及场景搭建时,白模搭建是 ⑥程序实现的首要子任务。 **输入**: -- `level-v--execution.md` — 关卡执行案(空间指南) -- `scene-v-.md` — 场景设计案(氛围参考) +- `关卡-v-<名称>-执行案.md` — 关卡执行案(空间指南) +- `场景-v-<名称>.md` — 场景设计案(氛围参考) - 系统执行案(交互物/收集品清单) - `Content/BlockingStarterPack/` — BSP 资产 **输出**: - `Content/Maps/LVL_V.umap` — 白模关卡文件 -- `docs/technical/level-v-build-report.md` — 搭建报告(偏差记录) +- `docs/technical/关卡-v-搭建报告.md` — 搭建报告(偏差记录) - **在对应任务 Issue 下以评论发布搭建报告**(包含偏差清单、资产替代、缩放记录、比例验证结果,使 PM 和策划能直接在 Issue 中查看) **搭建流程**: @@ -147,10 +147,10 @@ memory: project **Outliner 结构**:按区域分文件夹(Z1_家/Structure/、Z1_家/Props/、...),Global/ 放边界和光照。 **搭建报告**:逐区域对照文档要求记录偏差,包含资产替代清单、缩放记录、未实现项、比例验证结果。**报告必须同时**: -1. 写入 `docs/technical/level-v-build-report.md`(本地文件) +1. 写入 `docs/technical/关卡-v-搭建报告.md`(本地文件) 2. 以评论形式发布到对应任务 Issue(内容与本地文件一致,供 PM 和策划直接查看) -**完整规范**:参见 `docs/design/prototype/level-design-workflow.md` 第四章。 +**完整规范**:参见 `docs/design/prototype/关卡设计工作流.md` 第四章。 ### 工作流 C:代码实现(步骤⑥子任务 6b-6f) @@ -292,22 +292,21 @@ memory: project ## 关键文件路径 ### 你产出和维护: -- `docs/technical/-tech.md` — 技术设计文档 -- `docs/technical/notes/*.md` — 架构决策、技术选型笔记、经验教训 +- `docs/technical/<系统名>-技术方案.md` — 技术设计文档 +- `docs/technical/笔记/*.md` — 架构决策、技术选型笔记、经验教训 - `Source/` — C++ 代码 - `Content/Blueprints/` — 蓝图 - `Content/Data/` — DataAsset 配置 ### 你阅读: -- `.claude/refs/development-workflow.md` — 流水线定义、质量标准 - 项目管理工具 Issues — 查看分配给你的任务和流水线状态(参见 `.claude/skills/gitea-collab.md`) -- `docs/plans/-roadmap.md` — 版本划分、范围 -- `docs/design/concept.md` — 游戏方向参考 -- `docs/design//.md` — 系统设计概览 -- `docs/design//-execution.md` — 行为规则(你的主要输入) +- `docs/plans/<阶段>-路线图.md` — 版本划分、范围 +- `docs/design/概念草案.md` — 游戏方向参考 +- `docs/design//<系统名>.md` — 系统设计概览 +- `docs/design//<系统名>-执行案.md` — 行为规则(你的主要输入) - `GameConfig/*.csv` / `*.json` — 可调参数 -- `docs/plans/reviews/-review.md` — PM 质量门审查结果 -- `docs/art/style-guide.md` — 视觉方向参考(集成美术时阅读) +- `docs/plans/reviews/<任务ID>-审查记录.md` — PM 质量门审查结果 +- `docs/art/美术风格指南.md` — 视觉方向参考(集成美术时阅读) --- diff --git a/.claude/agents/game-pm.md b/.claude/agents/game-pm.md index c63afca..7174e99 100644 --- a/.claude/agents/game-pm.md +++ b/.claude/agents/game-pm.md @@ -30,9 +30,6 @@ memory: project ## 2. 参考文档与项目管理工具 -开始工作前,必须先阅读: -- `.claude/refs/development-workflow.md` — 流水线定义、阶段划分、质量门标准(**首先阅读**) - ### 项目管理工具 进度管理(任务列表、流水线状态、角色汇报)全部通过项目管理工具追踪。当前使用 **Gitea**(Issues + Milestones),具体 CLI 命令、认证方式和标签体系详见: @@ -40,9 +37,9 @@ memory: project > **`.claude/skills/gitea-collab.md`** — Gitea 协作工具完整参考 **保留在本地的文档**(不在项目管理工具中管理): -- `docs/plans/prototype-roadmap.md` — 阶段路线图(信息量太大) -- `docs/plans/reviews/-review.md` — 审查记录(详细结构化文档) -- `docs/plans/work-log.md` — 工作日志 +- `docs/plans/原型阶段-路线图.md` — 阶段路线图(信息量太大) +- `docs/plans/reviews/-审查记录.md` — 审查记录(详细结构化文档) +- `docs/plans/工作日志.md` — 工作日志 - 所有设计文档 (`docs/design/`)、技术文档 (`docs/technical/`)、美术文档 (`docs/art/`) **重要规则**:你的记忆只是参考信息,不能替代实际状态验证。"记忆说文件 X 存在" ≠ "X 现在存在"——使用前必须验证。 @@ -87,7 +84,7 @@ memory: project ### 审查后强制操作(无论谁执行审查) -- [ ] 在 `docs/plans/reviews/-review.md` 写了审查记录 +- [ ] 在 `docs/plans/reviews/-审查记录.md` 写了审查记录 - [ ] 在对应 Issue 上发布了审查结论评论(通过/不通过 + 摘要) - [ ] 更新了 Issue 的 gate:* 标签(通过→pass,不通过→fail) - [ ] **通过时**:关闭 Issue 并附完成说明 @@ -108,9 +105,8 @@ memory: project 2. **获取活跃任务列表** → 所有进行中的任务 3. **读取流水线追踪器状态** → 理解流水线位置 4. **读取近期角色汇报** → 了解最新进展 -5. **检查本地审查记录**(如有):检查 `docs/plans/reviews/` 中的近期质量门审查 -6. **交叉核对**流水线检查清单,确认当前流水线位置和阻塞点 -7. **向用户报告**:当前进度、阻塞点、建议的下一步行动 +5. **交叉核对**流水线检查清单,确认当前流水线位置和阻塞点 +6. **向用户报告**:当前进度、阻塞点、建议的下一步行动 > 具体 CLI 命令参见 `.claude/skills/gitea-collab.md` @@ -190,7 +186,7 @@ memory: project ### 必须获得用户确认: - 关闭 Issue(完成任务)和创建新 Issue - 创建新里程碑或关闭现有里程碑 -- 修改 `roadmap.md` 或 `prototype-roadmap.md` +- 修改 `路线图.md` 或 `原型阶段-路线图.md` - 质量门不通过后退回工作 - 重大偏差处理(回退或开新版本) - 阶段转换 @@ -234,8 +230,8 @@ memory: project |------|------|---------| | 任务追踪 | **项目管理工具 Issues**(唯一真实来源) | 任务状态变化 | | 流水线进度 | **Pipeline Tracker** | 流水线步骤变化 | -| 阶段路线图 | `docs/plans/-roadmap.md` | 阶段开始、迭代调整 | -| 审查记录 | `docs/plans/reviews/-review.md` | 每次质量门审查 | +| 阶段路线图 | `docs/plans/<阶段>-路线图.md` | 阶段开始、迭代调整 | +| 审查记录 | `docs/plans/reviews/-审查记录.md` | 每次质量门审查 | > 审查记录格式参见 `.claude/skills/quality-gate-review.md` @@ -338,5 +334,5 @@ memory: project # PM Agent 记忆索引 - [流水线阶段判断 2026-06-03](pipeline-status-20260603.md) — v0.1 处于阶段④执行案完善中,质量门未通过 -- [Roadmap 对齐问题](roadmap-alignment.md) — roadmap.md 缺少 v0.5-v0.7,需与 game-vision.md 对齐 +- [Roadmap 对齐问题](roadmap-alignment.md) — 路线图.md 缺少 v0.5-v0.7,需与游戏愿景.md 对齐 - [设计文档质量审查](design-doc-review.md) — 交互系统技术越界、收集系统缺v0.1执行细节、边界情况不足 diff --git a/.claude/agents/game-reviewer.md b/.claude/agents/game-reviewer.md index 393a688..05d7c7e 100644 --- a/.claude/agents/game-reviewer.md +++ b/.claude/agents/game-reviewer.md @@ -31,7 +31,6 @@ memory: project 开始工作前,必须先阅读: - `.claude/skills/quality-gate-review.md` — **4 道质量门标准、阶段对应标准、审查流程**(核心技能) - `.claude/skills/gitea-collab.md` — Gitea CLI 命令和操作规范 -- `.claude/refs/development-workflow.md` — 流水线定义和阶段划分 --- @@ -56,7 +55,7 @@ memory: project ### 步骤 4:执行强制操作 **必须**完成以下所有操作(缺一不可): -1. ✅ 在 `docs/plans/reviews/-review.md` 写审查记录 +1. ✅ 在 `docs/plans/reviews/-审查记录.md` 写审查记录 2. ✅ 在对应 Issue 上发布审查结论评论(通过/不通过 + 摘要) 3. ✅ 更新 Issue 的 gate:* 标签 4. ✅ **通过时**:关闭 Issue(附完成说明) @@ -72,7 +71,7 @@ node scripts/gitea.js --role pm issue comment --body "## 质量门审 **质量门**:[执行案/程序设计/美术资产/程序实现] **审查日期**:YYYY-MM-DD -**审查记录**:docs/plans/reviews/-review.md +**审查记录**:docs/plans/reviews/-审查记录.md ### 结论 [一句话总结] @@ -89,7 +88,7 @@ node scripts/gitea.js --role pm issue comment --body "## 质量门审 **质量门**:[执行案/程序设计/美术资产/程序实现] **审查日期**:YYYY-MM-DD -**审查记录**:docs/plans/reviews/-review.md +**审查记录**:docs/plans/reviews/-审查记录.md ### 结论 [一句话总结] diff --git a/.claude/refs/development-workflow.md b/.claude/refs/development-workflow.md index e31eeb2..4bd0f75 100644 --- a/.claude/refs/development-workflow.md +++ b/.claude/refs/development-workflow.md @@ -66,7 +66,7 @@ #### 产出 -**玩法草案文档**(`docs/design/concept.md`),包含以下 7 个字段: +**玩法草案文档**(`docs/design/概念草案.md`),包含以下 7 个字段: 1. **一句话描述** — 用一句话说清楚这是什么游戏 2. **玩家核心游玩内容与感受** — 玩家在游戏中的核心操作和活动,以及游戏希望带给玩家的情感基调、视觉风格和整体感受 @@ -76,7 +76,7 @@ 6. **市场定位与三大卖点** — 游戏在市场中的定位(品类、平台、价位),以及最能吸引玩家的三个核心卖点 7. **参考** — 灵感来源(其他游戏、电影、书、某种经历) -**美术风格指南**(`docs/art/style-guide.md`)— 确定视觉方向。 +**美术风格指南**(`docs/art/美术风格指南.md`)— 确定视觉方向。 **技术可行性评估** — 评估核心玩法在目标引擎/平台上的实现可行性。 @@ -107,7 +107,7 @@ | 层级 | 定位 | 比喻 | 特点 | |------|------|------|------| -| **草案** (concept.md) | 给游戏**定调** | 灵魂 | 回答"这个游戏是什么",简略但方向明确 | +| **草案** (概念草案.md) | 给游戏**定调** | 灵魂 | 回答"这个游戏是什么",简略但方向明确 | | **设计案** | 给游戏**定骨架** | 骨架 | 基于草案的原则展开系统设计,定义有哪些系统、系统关系、核心行为 | | **执行案** | 给游戏**填血肉** | 血肉 | 细化到程序可直接实现的交互规则和行为细节 | @@ -123,7 +123,7 @@ #### 阶段路线图 -原型阶段开始时,产出**阶段路线图**(`docs/plans/prototype-roadmap.md`): +原型阶段开始时,产出**阶段路线图**(`docs/plans/原型阶段-路线图.md`): - 计划分几个版本迭代 - 每个版本探索哪个方向(验证什么假设) @@ -149,10 +149,10 @@ ``` docs/design/prototype/ - player-controller.md # 设计案 - player-controller-execution.md # 执行案(含迭代版本表头) - interaction-system.md - interaction-system-execution.md + 玩家控制器.md # 设计案 + 玩家控制器-执行案.md # 执行案(含迭代版本表头) + 交互系统.md + 交互系统-执行案.md ... ``` @@ -195,7 +195,7 @@ docs/design/prototype/ #### 阶段路线图 -批量生产阶段开始时,产出**阶段路线图**(`docs/plans/production-roadmap.md`): +批量生产阶段开始时,产出**阶段路线图**(`docs/plans/批量生产阶段-路线图.md`): - 计划分几个版本迭代 - 每个版本的主要内容范围 @@ -212,8 +212,8 @@ docs/design/prototype/ ``` docs/design/production/ - player-controller.md # 在原型基础上更新 - player-controller-execution.md # 继续迭代,追加新的迭代记录 + 玩家控制器.md # 在原型基础上更新 + 玩家控制器-执行案.md # 继续迭代,追加新的迭代记录 ... ``` @@ -357,7 +357,7 @@ docs/design/production/ 6. **版本间的递进关系**:为什么先做这些后做那些 7. **每个版本的验收标准**:怎样算"这个版本做完了" -**产出位置**:`docs/plans/prototype-roadmap.md` 或 `docs/plans/production-roadmap.md` +**产出位置**:`docs/plans/原型阶段-路线图.md` 或 `docs/plans/批量生产阶段-路线图.md` **版本编号规则**: - 原型阶段:`v0.1`、`v0.2`、`v0.3`…… @@ -432,16 +432,16 @@ docs/design/production/ **产出形式**: - 每个系统一份执行案,放在 `docs/design/<阶段>/` 目录下 -- 文件命名:`<系统名>-execution.md`(如 `player-controller-execution.md`) +- 文件命名:`<系统名>-执行案.md`(如 `玩家控制器-执行案.md`) - 不按版本分文件,通过迭代记录表头追踪变更 -- **关卡执行案**(如有场景搭建需求):文件命名 `level-v--execution.md`,产出模板参见 `.claude/refs/level-execution-template.md` +- **关卡执行案**(如有场景搭建需求):文件命名 `关卡-v-<名称>-执行案.md`,产出模板参见 `.claude/refs/关卡执行案模板.md` **关卡执行案**: - 当版本开发涉及场景搭建时,策划额外产出一份关卡执行案 - 关卡执行案将场景设计案的氛围描述转化为空间精度搭建指南(坐标、尺寸、BSP 资产映射) - 使用混合坐标体系:区域用场景绝对坐标,区域内物件用相对偏移坐标 - 交互物和收集品的位置标注必须与交互系统/收集系统执行案交叉引用 -- 完整规范参见 `docs/design/prototype/level-design-workflow.md` +- 完整规范参见 `docs/design/prototype/关卡设计工作流.md` --- @@ -468,7 +468,7 @@ docs/design/production/ - **不通过** → 退回策划修改,列出具体问题清单 - **争议** → PM 与策划对判定有分歧时,由用户最终裁决 -**产出**:PM 审查记录(记录在 `docs/plans/reviews/<任务ID>-review.md`) +**产出**:PM 审查记录(记录在 `docs/plans/reviews/<任务ID>-审查记录.md`) --- @@ -495,7 +495,7 @@ docs/design/production/ | 数据流 | 允许硬编码 | 数据应配置化 | | 美术需求 | 允许简化描述 | 必须具体到尺寸和数量 | -**产出位置**:`docs/technical/<系统名>-tech.md` +**产出位置**:`docs/technical/<系统名>-技术方案.md` --- @@ -534,7 +534,7 @@ docs/design/production/ **产出位置**: - 资产放 `Content/` 对应目录 -- 清单记录在 `docs/art/asset-manifest.md` 或直接在技术方案中更新 +- 清单记录在 `docs/art/资产清单.md` 或直接在技术方案中更新 --- @@ -564,13 +564,13 @@ docs/design/production/ **白模搭建子任务(6a)**: 当版本开发涉及场景搭建时,⑥的第一个子任务是白模关卡搭建: -- 读取关卡执行案 `level-v--execution.md` 和场景设计案 +- 读取关卡执行案 `关卡-v-<名称>-执行案.md` 和场景设计案 - 使用 `Content/BlockingStarterPack/` 资产在 UE5 编辑器中搭建白模关卡 - 按区域分文件夹组织 Actor(命名规范:`LVL___`) - 完成比例验证(角色可通过门洞、摄像机不穿墙、流线通行) -- 产出搭建报告 `docs/technical/level-v-build-report.md` 记录偏差 +- 产出搭建报告 `docs/technical/关卡-v-搭建报告.md` 记录偏差 - **搭建报告必须以评论形式发布到对应任务 Issue**(与本地文件内容一致) -- 完整搭建流程参见 `docs/design/prototype/level-design-workflow.md` 第四章 +- 完整搭建流程参见 `docs/design/prototype/关卡设计工作流.md` 第四章 **阶段差异**: @@ -611,7 +611,7 @@ docs/design/production/ - **不通过(重大)** → PM 提出处理建议(回退步骤或开新版本),由用户最终决定 - **争议** → PM 与程序对判定有分歧时,由用户最终裁决 -**产出**:PM 审查记录(记录在 `docs/plans/reviews/<任务ID>-review.md`) +**产出**:PM 审查记录(记录在 `docs/plans/reviews/<任务ID>-审查记录.md`) --- @@ -656,14 +656,14 @@ PM 在每次 `/plan` 调用时,先判断宏观阶段,再针对**当前版本 | 检查项 | 判断方式 | 结果 | |--------|----------|------| -| 项目处于哪个开发阶段? | 检查 `concept.md` → 检查核心玩法是否已有可玩原型 → 检查内容是否已完整 | 草案 / 原型 / 批量生产 / 测试发布 | +| 项目处于哪个开发阶段? | 检查 `概念草案.md` → 检查核心玩法是否已有可玩原型 → 检查内容是否已完整 | 草案 / 原型 / 批量生产 / 测试发布 | ### 版本流水线检查 | 检查项 | 检查方式 | 通过条件 | |--------|----------|----------| | ① 设计案是否存在且完整? | 检查 `docs/design/<阶段>/` 中的设计文档和索引 | 覆盖所有主要系统,有索引串联 | -| ② 阶段路线图是否存在? | 检查 `docs/plans/<阶段>-roadmap.md` | 版本列表、每版本目标、递进关系明确 | +| ② 阶段路线图是否存在? | 检查 `docs/plans/<阶段>-路线图.md` | 版本列表、每版本目标、递进关系明确 | | ③ 执行案是否齐全? | 检查 `docs/design/<阶段>/` 对应执行案 | 每个涉及系统的核心行为规则都已明确 | | **PM 审查**:执行案质量门 | 对照质量标准逐项检查 | 完整性、清晰性、边界情况通过 | | ④ 程序设计方案是否齐全? | 检查 `docs/technical/` 对应文档 | 每个执行案都有对应技术方案 | diff --git a/.claude/refs/level-execution-template.md b/.claude/refs/level-execution-template.md index 102efea..dc0a7f2 100644 --- a/.claude/refs/level-execution-template.md +++ b/.claude/refs/level-execution-template.md @@ -2,7 +2,7 @@ > 本模板供策划产出关卡执行案时使用。关卡执行案是场景设计案的"空间精度版本"——将氛围描述转化为带有坐标、尺寸和资产建议的结构化搭建指南,供程序在 UE5 编辑器中搭建白模。 > -> 文件命名:`level-v--execution.md`(如 `level-v01-suburban-execution.md`) +> 文件命名:`关卡-v-<名称>-执行案.md`(如 `关卡-v01-城郊街区-执行案.md`) > 存放位置:`docs/design/<阶段>/`(与其他执行案同目录) --- @@ -49,7 +49,7 @@ | ... | | | | | | | Zn | | | | | | -> 标识色使用 BSP 材质名(参见 `blockout-asset-reference.md`),程序用对应材质标识区域。 +> 标识色使用 BSP 材质名(参见 `白模资产参考.md`),程序用对应材质标识区域。 ### 2.2 交通流线 @@ -119,7 +119,7 @@ - 填写 BSP 资产类别名和组合方式(如 "Wall_400x300 × 2 叠加") - 程序负责映射到引擎中的具体资产路径 - 如无精确匹配,写"Primitives 组合"并注明替代意图 -- 参见 `.claude/refs/blockout-asset-reference.md` 中的替代方案 +- 参见 `.claude/refs/白模资产参考.md` 中的替代方案 #### 3.x.3 布景物清单 @@ -137,7 +137,7 @@ | 交互编号 | 物件名称 | 交互类型 | 相对原点偏移 (ΔX,ΔY,ΔZ) | 触发半径 (cm) | 引用 | |---------|---------|---------|----------------------|-------------|------| -| Zx-I01 | | | (200,400,10) | | interaction-system-execution #n | +| Zx-I01 | | | (200,400,10) | | 交互系统-执行案 #n | | Zx-I02 | | | | | | | ... | | | | | | @@ -150,7 +150,7 @@ | 收集编号 | 物品名称 | 稀有度 | 相对原点偏移 (ΔX,ΔY,ΔZ) | 引用 | |---------|---------|--------|----------------------|------| -| Zx-C01 | | | (500,200,0) | collection-system-execution #n | +| Zx-C01 | | | (500,200,0) | 收集系统-执行案 #n | | Zx-C02 | | | | | | ... | | | | | | @@ -187,7 +187,7 @@ | # | 物品名称 | 所在区域 | 绝对坐标 (X,Y,Z) | 稀有度 | 引用 | |---|---------|---------|-----------------|--------|------| -| 1 | | | | | collection-system-execution #n | +| 1 | | | | | 收集系统-执行案 #n | | 2 | | | | | | | ... | | | | | | @@ -240,6 +240,6 @@ ### 与场景设计案的关系 -- 场景设计案(`scene-vXX-.md`)= **氛围愿景** — 描述感觉、氛围、叙事意图 +- 场景设计案(`场景-v-<名称>.md`)= **氛围愿景** — 描述感觉、氛围、叙事意图 - 关卡执行案 = **空间精度搭建指南** — 坐标、尺寸、资产映射 - 两者是互补关系,不是替代关系。程序搭建时两个文档都需要参考。 diff --git a/.claude/skills/gitea-collab.md b/.claude/skills/gitea-collab.md index 845d66e..6c52f4b 100644 --- a/.claude/skills/gitea-collab.md +++ b/.claude/skills/gitea-collab.md @@ -75,7 +75,7 @@ description: "Gitea 协作工具 — CLI 命令速查、认证机制、Assignee | `gate:impl-pass` | 程序实现验收门通过 | | `gate:impl-fail` | 程序实现验收门未通过 | -> **注**:旧 Issue 上可能仍有 `pipeline:*` 和 `role:*` 标签,这些已不再使用,保留不管即可。 +> **注**:`pipeline:*` 和 `role:*` 标签已废弃并从 Gitea 上删除。如旧 Issue 上仍残留这些标签,忽略即可。 --- @@ -178,7 +178,7 @@ node scripts/gitea.js test | 角色归属 | Assignee | 通过 `--assignees` 指派 | | 流水线步骤 | Pipeline Tracker | Meta Issue 记录全局流水线状态 | | 角色汇报 | Issue 评论 | 各角色在对应 Issue 下评论 | -| 审查记录 | Issue 评论(摘要+链接)+ 本地 `docs/plans/reviews/` | 本地保留详细结构化文档 | +| 审查记录 | Issue 评论(摘要+链接)+ 本地 `docs/plans/reviews/` | 本地文件名格式 `<任务ID>-审查记录.md` | | 任务归档 | close Issue | 不需要本地 archive 文件 | --- @@ -266,7 +266,7 @@ node scripts/gitea.js --role pm issue comment --body "## 质量门审 **质量门**:[类型] **审查日期**:YYYY-MM-DD -**审查记录**:docs/plans/reviews/-review.md +**审查记录**:docs/plans/reviews/-审查记录.md ### 结论 [一句话总结] @@ -282,7 +282,7 @@ node scripts/gitea.js --role pm issue close --body "## 任务完成 ✔ **完成日期**:YYYY-MM-DD **产出**:path/to/output -**审查记录**:docs/plans/reviews/-review.md" +**审查记录**:docs/plans/reviews/-审查记录.md" ``` --- @@ -315,7 +315,7 @@ node scripts/gitea.js --role pm issue comments # 创建 Issue(必须指定 assignees) node scripts/gitea.js --role pm issue create \ --title "D-001 交互系统执行案" \ - --body "## 任务信息\n- **任务ID**: D-001\n- **所属版本**: v0.1\n- **角色**: 策划\n- **预期产出**: docs/design/prototype/interaction-system-execution.md\n..." \ + --body "## 任务信息\n- **任务ID**: D-001\n- **所属版本**: v0.1\n- **角色**: 策划\n- **预期产出**: docs/design/prototype/交互系统-执行案.md\n..." \ --milestone \ --assignees ai-designer diff --git a/.claude/skills/quality-gate-review.md b/.claude/skills/quality-gate-review.md index d8173a3..8d370cc 100644 --- a/.claude/skills/quality-gate-review.md +++ b/.claude/skills/quality-gate-review.md @@ -24,7 +24,7 @@ description: "质量门审查技能 — 4 道质量门标准、阶段对应标 - 根据当前开发阶段选择对应标准(原型 vs 批量生产,见"阶段对应标准") ### 3. 写审查记录(本地文件) -- 路径:`docs/plans/reviews/-review.md` +- 路径:`docs/plans/reviews/-审查记录.md` - 格式见下方"审查记录格式" ### 4. Issue 评论(强制) @@ -117,7 +117,7 @@ description: "质量门审查技能 — 4 道质量门标准、阶段对应标 ## 审查记录格式 -文件路径:`docs/plans/reviews/-review.md` +文件路径:`docs/plans/reviews/-审查记录.md` ```markdown # [任务 ID] 审查报告 @@ -148,7 +148,7 @@ description: "质量门审查技能 — 4 道质量门标准、阶段对应标 审查完成后,**必须**逐项确认以下操作: -- [ ] 在 `docs/plans/reviews/-review.md` 写了审查记录 +- [ ] 在 `docs/plans/reviews/-审查记录.md` 写了审查记录 - [ ] 在对应 Issue 上发布了审查结论评论(通过/不通过 + 摘要) - [ ] 更新了 Issue 的 gate:* 标签(通过→pass,不通过→fail) - [ ] **通过时**:关闭 Issue 并附完成说明 diff --git a/.claude/skills/requirements-analysis/SKILL.md b/.claude/skills/requirements-analysis/SKILL.md index 1f7ca81..89d89c5 100644 --- a/.claude/skills/requirements-analysis/SKILL.md +++ b/.claude/skills/requirements-analysis/SKILL.md @@ -21,10 +21,10 @@ description: > 按序阅读以下文档,获取完整的上下文信息: -1. **执行文档** (`docs/design//-execution.md`) — 行为规则细节(主要输入) -2. **系统设计文档** (`docs/design//.md`) — 全局上下文 +1. **执行文档** (`docs/design//<系统名>-执行案.md`) — 行为规则细节(主要输入) +2. **系统设计文档** (`docs/design//<系统名>.md`) — 全局上下文 3. **配置表** (`GameConfig/`) — 可调参数 -4. **概念文档** (`docs/design/concept.md`) — 方向参考(需要理解设计意图时查阅) +4. **概念文档** (`docs/design/概念草案.md`) — 方向参考(需要理解设计意图时查阅) --- @@ -134,7 +134,7 @@ description: > ## 输出 -最终产出为技术设计文档,保存到 `docs/technical/-tech.md`。 +最终产出为技术设计文档,保存到 `docs/technical/<系统名>-技术方案.md`。 文档必须遵循 `references/output-template.md` 中定义的标准模板结构。8 步分析的结果整合到模板的对应章节中,同时保留现有的必要章节(美术资源需求、数据流、可调参数汇总、文件结构)。 diff --git a/.claude/skills/requirements-analysis/references/diagram-guide.md b/.claude/skills/requirements-analysis/references/diagram-guide.md index 67773f5..9869364 100644 --- a/.claude/skills/requirements-analysis/references/diagram-guide.md +++ b/.claude/skills/requirements-analysis/references/diagram-guide.md @@ -280,11 +280,11 @@ flowchart TD ### 3.3 项目实际案例参考 -**需要时序图的特性**(从现有 `interaction-system-tech.md` 提取): +**需要时序图的特性**(从现有 `交互系统-技术方案.md` 提取): - 完整交互流程(Enter → AnimLock → Active → Exit) - 拾取流程(交互系统 → 物品系统 → 收集系统) -**不需要时序图的特性**(从现有 `player-controller-tech.md` 提取): +**不需要时序图的特性**(从现有 `玩家控制器-技术方案.md` 提取): - SpringArm 参数配置(纯构造函数设置) - CMC 移动参数调整(纯配置) diff --git a/.claude/skills/requirements-analysis/references/examples.md b/.claude/skills/requirements-analysis/references/examples.md index cf9f3dd..7292f8b 100644 --- a/.claude/skills/requirements-analysis/references/examples.md +++ b/.claude/skills/requirements-analysis/references/examples.md @@ -8,9 +8,9 @@ | 示例 | 来源文档 | |------|---------| -| 交互系统 | `docs/technical/interaction-system-tech.md` | -| 角色控制 | `docs/technical/player-controller-tech.md` | -| 收集系统 | `docs/technical/collection-system-tech.md` | +| 交互系统 | `docs/technical/交互系统-技术方案.md` | +| 角色控制 | `docs/technical/玩家控制器-技术方案.md` | +| 收集系统 | `docs/technical/收集系统-技术方案.md` | --- diff --git a/.claude/skills/requirements-analysis/references/output-template.md b/.claude/skills/requirements-analysis/references/output-template.md index 02148ef..21d6085 100644 --- a/.claude/skills/requirements-analysis/references/output-template.md +++ b/.claude/skills/requirements-analysis/references/output-template.md @@ -10,7 +10,7 @@ # <系统名称> 技术设计文档(<版本号> <阶段>) > 任务ID: <任务编号> -> 对应执行案: `<执行案文件路径>` +> 对应执行案: `docs/design//<系统名>-执行案.md` > 关联系统: <上游/下游/平行系统列表> > 阶段: 原型 / 批量生产 / 测试 > 日期: diff --git a/ChildHood.uproject b/ChildHood.uproject index 03f1fc0..0b05642 100644 --- a/ChildHood.uproject +++ b/ChildHood.uproject @@ -30,6 +30,13 @@ { "Name": "GameplayStateTree", "Enabled": true + }, + { + "Name": "PythonScriptPlugin", + "Enabled": true, + "TargetAllowList": [ + "Editor" + ] } ] -} \ No newline at end of file +} diff --git a/docs/art/3d/models/boy/prompts.md b/docs/art/3d/models/boy/提示词.md similarity index 100% rename from docs/art/3d/models/boy/prompts.md rename to docs/art/3d/models/boy/提示词.md diff --git a/docs/art/style-guide.md b/docs/art/美术风格指南.md similarity index 100% rename from docs/art/style-guide.md rename to docs/art/美术风格指南.md diff --git a/docs/design/prototype/v01-scope.md b/docs/design/prototype/v01-范围.md similarity index 100% rename from docs/design/prototype/v01-scope.md rename to docs/design/prototype/v01-范围.md diff --git a/docs/design/prototype/protagonist-character.md b/docs/design/prototype/主角设计.md similarity index 100% rename from docs/design/prototype/protagonist-character.md rename to docs/design/prototype/主角设计.md diff --git a/docs/design/prototype/interaction-system-execution.md b/docs/design/prototype/交互系统-执行案.md similarity index 100% rename from docs/design/prototype/interaction-system-execution.md rename to docs/design/prototype/交互系统-执行案.md diff --git a/docs/design/prototype/interaction-system.md b/docs/design/prototype/交互系统.md similarity index 100% rename from docs/design/prototype/interaction-system.md rename to docs/design/prototype/交互系统.md diff --git a/docs/design/prototype/level-v01-suburban-execution.md b/docs/design/prototype/关卡-v01-城郊小街-执行案.md similarity index 100% rename from docs/design/prototype/level-v01-suburban-execution.md rename to docs/design/prototype/关卡-v01-城郊小街-执行案.md diff --git a/docs/design/prototype/level-design-workflow.md b/docs/design/prototype/关卡设计工作流.md similarity index 100% rename from docs/design/prototype/level-design-workflow.md rename to docs/design/prototype/关卡设计工作流.md diff --git a/docs/design/prototype/narrative-framework.md b/docs/design/prototype/叙事框架.md similarity index 100% rename from docs/design/prototype/narrative-framework.md rename to docs/design/prototype/叙事框架.md diff --git a/docs/design/prototype/scene-v01-suburban.md b/docs/design/prototype/场景-v01-城郊小街.md similarity index 100% rename from docs/design/prototype/scene-v01-suburban.md rename to docs/design/prototype/场景-v01-城郊小街.md diff --git a/docs/design/prototype/scene-world.md b/docs/design/prototype/场景与世界观.md similarity index 100% rename from docs/design/prototype/scene-world.md rename to docs/design/prototype/场景与世界观.md diff --git a/docs/design/prototype/brainstorm-2026-06-01-vision-pillars-world.md b/docs/design/prototype/头脑风暴-2026-06-01-愿景支柱与世界观.md similarity index 100% rename from docs/design/prototype/brainstorm-2026-06-01-vision-pillars-world.md rename to docs/design/prototype/头脑风暴-2026-06-01-愿景支柱与世界观.md diff --git a/docs/design/prototype/brainstorm-2026-06-04-era-tech-inspirations.md b/docs/design/prototype/头脑风暴-2026-06-04-时代与科技灵感.md similarity index 100% rename from docs/design/prototype/brainstorm-2026-06-04-era-tech-inspirations.md rename to docs/design/prototype/头脑风暴-2026-06-04-时代与科技灵感.md diff --git a/docs/design/prototype/brainstorm-2026-06-05-nostalgia-culture.md b/docs/design/prototype/头脑风暴-2026-06-05-怀旧文化.md similarity index 100% rename from docs/design/prototype/brainstorm-2026-06-05-nostalgia-culture.md rename to docs/design/prototype/头脑风暴-2026-06-05-怀旧文化.md diff --git a/docs/design/prototype/minigame-system.md b/docs/design/prototype/小游戏系统.md similarity index 100% rename from docs/design/prototype/minigame-system.md rename to docs/design/prototype/小游戏系统.md diff --git a/docs/design/prototype/collection-system-execution.md b/docs/design/prototype/收集系统-执行案.md similarity index 100% rename from docs/design/prototype/collection-system-execution.md rename to docs/design/prototype/收集系统-执行案.md diff --git a/docs/design/prototype/collection-system.md b/docs/design/prototype/收集系统.md similarity index 100% rename from docs/design/prototype/collection-system.md rename to docs/design/prototype/收集系统.md diff --git a/docs/design/prototype/game-vision.md b/docs/design/prototype/游戏愿景.md similarity index 100% rename from docs/design/prototype/game-vision.md rename to docs/design/prototype/游戏愿景.md diff --git a/docs/design/prototype/player-controller-execution.md b/docs/design/prototype/玩家控制器-执行案.md similarity index 100% rename from docs/design/prototype/player-controller-execution.md rename to docs/design/prototype/玩家控制器-执行案.md diff --git a/docs/design/prototype/player-controller.md b/docs/design/prototype/玩家控制器.md similarity index 100% rename from docs/design/prototype/player-controller.md rename to docs/design/prototype/玩家控制器.md diff --git a/docs/design/concept.md b/docs/design/概念草案.md similarity index 100% rename from docs/design/concept.md rename to docs/design/概念草案.md diff --git a/docs/plans/archive/draft/pre-draft.md b/docs/plans/archive/draft/草案前记录.md similarity index 100% rename from docs/plans/archive/draft/pre-draft.md rename to docs/plans/archive/draft/草案前记录.md diff --git a/docs/plans/reports/dev-report.md b/docs/plans/reports/程序汇报.md similarity index 100% rename from docs/plans/reports/dev-report.md rename to docs/plans/reports/程序汇报.md diff --git a/docs/plans/reports/design-report.md b/docs/plans/reports/策划汇报.md similarity index 100% rename from docs/plans/reports/design-report.md rename to docs/plans/reports/策划汇报.md diff --git a/docs/plans/reports/art-report.md b/docs/plans/reports/美术汇报.md similarity index 100% rename from docs/plans/reports/art-report.md rename to docs/plans/reports/美术汇报.md diff --git a/docs/plans/reviews/D-001-review.md b/docs/plans/reviews/D-001-审查记录.md similarity index 100% rename from docs/plans/reviews/D-001-review.md rename to docs/plans/reviews/D-001-审查记录.md diff --git a/docs/plans/reviews/P-002-review-r2.md b/docs/plans/reviews/P-002-审查记录-r2.md similarity index 100% rename from docs/plans/reviews/P-002-review-r2.md rename to docs/plans/reviews/P-002-审查记录-r2.md diff --git a/docs/plans/reviews/P-002-review.md b/docs/plans/reviews/P-002-审查记录.md similarity index 100% rename from docs/plans/reviews/P-002-review.md rename to docs/plans/reviews/P-002-审查记录.md diff --git a/docs/plans/reviews/P-008-review.md b/docs/plans/reviews/P-008-审查记录.md similarity index 100% rename from docs/plans/reviews/P-008-review.md rename to docs/plans/reviews/P-008-审查记录.md diff --git a/docs/plans/reviews/level-v01-review.md b/docs/plans/reviews/关卡-v01-审查记录.md similarity index 100% rename from docs/plans/reviews/level-v01-review.md rename to docs/plans/reviews/关卡-v01-审查记录.md diff --git a/docs/plans/prototype-roadmap.md b/docs/plans/原型阶段-路线图.md similarity index 100% rename from docs/plans/prototype-roadmap.md rename to docs/plans/原型阶段-路线图.md diff --git a/docs/plans/work-log.md b/docs/plans/工作日志.md similarity index 100% rename from docs/plans/work-log.md rename to docs/plans/工作日志.md diff --git a/docs/plans/current.md b/docs/plans/当前计划.md similarity index 100% rename from docs/plans/current.md rename to docs/plans/当前计划.md diff --git a/docs/plans/roadmap.md b/docs/plans/路线图.md similarity index 100% rename from docs/plans/roadmap.md rename to docs/plans/路线图.md diff --git a/docs/technical/gitea-api-guide.md b/docs/technical/Gitea API 指南.md similarity index 100% rename from docs/technical/gitea-api-guide.md rename to docs/technical/Gitea API 指南.md diff --git a/docs/technical/interaction-system-tech.md b/docs/technical/交互系统-技术方案.md similarity index 100% rename from docs/technical/interaction-system-tech.md rename to docs/technical/交互系统-技术方案.md diff --git a/docs/technical/level-v01-build-report.md b/docs/technical/关卡-v01-搭建报告.md similarity index 100% rename from docs/technical/level-v01-build-report.md rename to docs/technical/关卡-v01-搭建报告.md diff --git a/docs/technical/level-v01-build-guide.md b/docs/technical/关卡-v01-搭建指南.md similarity index 100% rename from docs/technical/level-v01-build-guide.md rename to docs/technical/关卡-v01-搭建指南.md diff --git a/docs/technical/feasibility-assessment.md b/docs/technical/技术可行性评估.md similarity index 100% rename from docs/technical/feasibility-assessment.md rename to docs/technical/技术可行性评估.md diff --git a/docs/technical/collection-system-tech.md b/docs/technical/收集系统-技术方案.md similarity index 100% rename from docs/technical/collection-system-tech.md rename to docs/technical/收集系统-技术方案.md diff --git a/docs/technical/player-controller-tech.md b/docs/technical/玩家控制器-技术方案.md similarity index 100% rename from docs/technical/player-controller-tech.md rename to docs/technical/玩家控制器-技术方案.md diff --git a/tools/level-builder/builder/__init__.py b/tools/level-builder/builder/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tools/level-builder/builder/scene_builder.py b/tools/level-builder/builder/scene_builder.py new file mode 100644 index 0000000..80d0c29 --- /dev/null +++ b/tools/level-builder/builder/scene_builder.py @@ -0,0 +1,256 @@ +"""UE5 场景构建器。 + +在 UE5 编辑器的 Python 环境中运行。读取 JSON 中间数据, +使用 unreal Python API 创建 Actor、设置 Transform/材质/Outliner 文件夹。 + +使用方式: + 在 UE5 编辑器 Output Log 中切换到 Python,执行: + exec(open(r"path/to/scene_builder.py").read()) + build_level(r"path/to/level_v01.json") +""" + +import json +import logging +import sys +from pathlib import Path + +# 尝试导入 unreal,失败时给出提示 +try: + import unreal + HAS_UNREAL = True +except ImportError: + HAS_UNREAL = False + +# 将项目根目录加入 sys.path 以支持 config 导入 +_SCRIPT_DIR = Path(__file__).resolve().parent +_TOOLS_DIR = _SCRIPT_DIR.parent.parent.parent +if str(_TOOLS_DIR) not in sys.path: + sys.path.insert(0, str(_TOOLS_DIR)) + +from tools.level_builder.config.asset_mapping import MESH_ASSETS +from tools.level_builder.config.material_mapping import MATERIAL_PATHS + +logger = logging.getLogger("level_builder.builder") + + +def build_level(json_path: str, clear_existing: bool = True, zones: list[str] = None): + """从 JSON 数据构建 UE5 关卡。 + + Args: + json_path: 中间 JSON 文件路径。 + clear_existing: 是否清除已有的 LVL_* Actor。 + zones: 仅构建指定区域(如 ["Z1", "Z3"]),None 表示全部。 + """ + if not HAS_UNREAL: + print("[错误] 未检测到 unreal 模块。此脚本必须在 UE5 编辑器 Python 环境中运行。") + return + + # 加载数据 + data = _load_json(json_path) + if not data: + return + + actors = data.get("actors", []) + print(f"[LevelBuilder] 加载 {len(actors)} 个 Actor 定义") + + # 可选:清除已有 LVL_* Actor + if clear_existing: + _clear_existing_actors() + + # 过滤区域 + if zones: + actors = [a for a in actors if a.get("zone_id") in zones or a.get("zone_id") == "GLOBAL"] + print(f"[LevelBuilder] 过滤为 {len(actors)} 个 Actor(区域: {zones})") + + # 获取编辑器子系统 + editor_subsystem = unreal.get_editor_subsystem(unreal.EditorActorSubsystem) + if not editor_subsystem: + print("[错误] 无法获取 EditorActorSubsystem") + return + + # 统计 + success = 0 + failed = 0 + build_log = [] + + for i, actor_def in enumerate(actors): + name = actor_def.get("actor_name", f"Actor_{i}") + asset_type = actor_def.get("asset_type", "static_mesh") + + try: + if asset_type == "player_start": + actor = _spawn_player_start(editor_subsystem, actor_def) + elif asset_type == "directional_light": + actor = _spawn_directional_light(editor_subsystem, actor_def) + elif asset_type == "sky_light": + actor = _spawn_sky_light(editor_subsystem, actor_def) + elif asset_type == "point_light": + actor = _spawn_point_light(editor_subsystem, actor_def) + else: + actor = _spawn_mesh_actor(editor_subsystem, actor_def) + + if actor: + success += 1 + build_log.append({"name": name, "status": "ok", **actor_def}) + else: + failed += 1 + build_log.append({"name": name, "status": "failed", "reason": "spawn returned None"}) + + except Exception as e: + failed += 1 + error_msg = str(e) + build_log.append({"name": name, "status": "error", "reason": error_msg}) + print(f" [错误] {name}: {error_msg}") + + # 进度 + if (i + 1) % 20 == 0: + print(f" 进度: {i + 1}/{len(actors)} ({success} 成功, {failed} 失败)") + + print(f"\n[LevelBuilder] 构建完成!") + print(f" 成功: {success}") + print(f" 失败: {failed}") + print(f" 总计: {len(actors)}") + + # 保存构建日志 + log_path = Path(json_path).parent / "build_log.json" + with open(log_path, "w", encoding="utf-8") as f: + json.dump(build_log, f, ensure_ascii=False, indent=2) + print(f" 日志: {log_path}") + + return build_log + + +def _load_json(path: str) -> dict: + """加载 JSON 文件。""" + try: + with open(path, "r", encoding="utf-8") as f: + return json.load(f) + except Exception as e: + print(f"[错误] 无法加载 JSON: {e}") + return None + + +def _clear_existing_actors(): + """清除场景中所有 LVL_ 前缀的 Actor。""" + editor_subsystem = unreal.get_editor_subsystem(unreal.EditorActorSubsystem) + all_actors = unreal.EditorLevelLibrary.get_all_level_actors() + lvl_actors = [a for a in all_actors if a.get_actor_label().startswith("LVL_")] + if lvl_actors: + print(f"[LevelBuilder] 清除 {len(lvl_actors)} 个已有 LVL_* Actor...") + for a in lvl_actors: + unreal.EditorLevelLibrary.destroy_actor(a) + else: + print("[LevelBuilder] 无已有 LVL_* Actor 需清除") + + +def _spawn_mesh_actor(editor_subsystem, actor_def: dict): + """生成 StaticMesh Actor。""" + asset_key = actor_def.get("asset_key", "") + if not asset_key or asset_key not in MESH_ASSETS: + print(f" [警告] {actor_def['actor_name']}: 资产 '{asset_key}' 未找到,使用默认 Cube") + asset_key = "Cube" + + mesh_path = MESH_ASSETS[asset_key]["path"] + static_mesh = unreal.load_asset(mesh_path) + if not static_mesh: + print(f" [警告] {actor_def['actor_name']}: 无法加载资产 '{mesh_path}'") + return None + + # 生成 + loc = actor_def.get("location", [0, 0, 0]) + actor = editor_subsystem.spawn_actor_from_object( + static_mesh, + unreal.Vector(loc[0], loc[1], loc[2]) + ) + + if not actor: + return None + + # 设置 Transform + rot = actor_def.get("rotation", [0, 0, 0]) + actor.set_actor_rotation(unreal.Rotator(rot[0], rot[1], rot[2])) + + scale = actor_def.get("scale", [1, 1, 1]) + actor.set_actor_scale3d(unreal.Vector(scale[0], scale[1], scale[2])) + + # 设置材质 + material_name = actor_def.get("material", "") + if material_name and material_name in MATERIAL_PATHS: + mat_path = MATERIAL_PATHS[material_name] + material = unreal.load_asset(mat_path) + if material: + mesh_comp = actor.get_component_by_class(unreal.StaticMeshComponent) + if mesh_comp: + mesh_comp.set_material(0, material) + + # 设置名称和文件夹 + actor.set_actor_label(actor_def["actor_name"]) + folder = actor_def.get("folder", "") + if folder: + actor.set_folder_path(folder) + + return actor + + +def _spawn_player_start(editor_subsystem, actor_def: dict): + """生成 PlayerStart Actor。""" + loc = actor_def.get("location", [0, 0, 0]) + actor = editor_subsystem.spawn_actor_from_class( + unreal.PlayerStart, + unreal.Vector(loc[0], loc[1], loc[2]) + ) + if actor: + rot = actor_def.get("rotation", [0, 0, 0]) + actor.set_actor_rotation(unreal.Rotator(rot[0], rot[1], rot[2])) + actor.set_actor_label(actor_def["actor_name"]) + folder = actor_def.get("folder", "") + if folder: + actor.set_folder_path(folder) + return actor + + +def _spawn_directional_light(editor_subsystem, actor_def: dict): + """生成 DirectionalLight Actor。""" + loc = actor_def.get("location", [0, 0, 500]) + actor = editor_subsystem.spawn_actor_from_class( + unreal.DirectionalLight, + unreal.Vector(loc[0], loc[1], loc[2]) + ) + if actor: + rot = actor_def.get("rotation", [-45, 315, 0]) + actor.set_actor_rotation(unreal.Rotator(rot[0], rot[1], rot[2])) + actor.set_actor_label(actor_def["actor_name"]) + folder = actor_def.get("folder", "") + if folder: + actor.set_folder_path(folder) + return actor + + +def _spawn_sky_light(editor_subsystem, actor_def: dict): + """生成 SkyLight Actor。""" + loc = actor_def.get("location", [0, 0, 0]) + actor = editor_subsystem.spawn_actor_from_class( + unreal.SkyLight, + unreal.Vector(loc[0], loc[1], loc[2]) + ) + if actor: + actor.set_actor_label(actor_def["actor_name"]) + folder = actor_def.get("folder", "") + if folder: + actor.set_folder_path(folder) + return actor + + +def _spawn_point_light(editor_subsystem, actor_def: dict): + """生成 PointLight Actor。""" + loc = actor_def.get("location", [0, 0, 0]) + actor = editor_subsystem.spawn_actor_from_class( + unreal.PointLight, + unreal.Vector(loc[0], loc[1], loc[2]) + ) + if actor: + actor.set_actor_label(actor_def["actor_name"]) + folder = actor_def.get("folder", "") + if folder: + actor.set_folder_path(folder) + return actor diff --git a/tools/level-builder/config/__init__.py b/tools/level-builder/config/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tools/level-builder/config/asset_mapping.py b/tools/level-builder/config/asset_mapping.py new file mode 100644 index 0000000..ceb67d2 --- /dev/null +++ b/tools/level-builder/config/asset_mapping.py @@ -0,0 +1,211 @@ +"""BSP 资产设计名 → UE5 内容路径映射。 + +数据来源: docs/technical/关卡-v01-搭建指南.md 第一章 (BSP 资产映射表) +资产根路径: Content/BlockingStarterPack/Meshes/ + +路径格式: /Game//. +""" + +# 资产路径前缀 +MESH_ROOT = "/Game/BlockingStarterPack/Meshes" +MATERIAL_ROOT = "/Game/BlockingStarterPack/Materials" + +MESH_ASSETS = { + # ---- 建筑 — 墙体 ---- + "Wall_400x300": { + "path": f"{MESH_ROOT}/Architecture/Walls/SM_Wall_400x300.SM_Wall_400x300", + "default_size": (400, 20, 300), + "category": "wall", + }, + "Wall_200x300": { + "path": f"{MESH_ROOT}/Architecture/Walls/SM_Wall_200x300.SM_Wall_200x300", + "default_size": (200, 20, 300), + "category": "wall", + }, + "Wall_100x300": { + "path": f"{MESH_ROOT}/Architecture/Walls/SM_Wall_100x300.SM_Wall_100x300", + "default_size": (100, 20, 300), + "category": "wall", + }, + "Wall_400x100": { + "path": f"{MESH_ROOT}/Architecture/Walls/SM_Wall_400x100.SM_Wall_400x100", + "default_size": (400, 20, 100), + "category": "wall", + }, + "WallDoor_200x300": { + "path": f"{MESH_ROOT}/Architecture/Walls/SM_WallDoor_200x300.SM_WallDoor_200x300", + "default_size": (200, 20, 300), + "category": "wall_door", + }, + "WallDoorGarage_400x300": { + "path": f"{MESH_ROOT}/Architecture/Walls/SM_WallDoorGarage_400x300.SM_WallDoorGarage_400x300", + "default_size": (400, 20, 300), + "category": "wall_door", + }, + "WallWindow_400x300": { + "path": f"{MESH_ROOT}/Architecture/Walls/SM_WallWindow_400x300.SM_WallWindow_400x300", + "default_size": (400, 20, 300), + "category": "wall_window", + }, + "WallWindowSmall_200x300": { + "path": f"{MESH_ROOT}/Architecture/Walls/SM_WallWindowSmall_200x300.SM_WallWindowSmall_200x300", + "default_size": (200, 20, 300), + "category": "wall_window", + }, + # ---- 建筑 — 地板 ---- + "Floor_1000x1000": { + "path": f"{MESH_ROOT}/Architecture/Floors/SM_Floor_1000x1000.SM_Floor_1000x1000", + "default_size": (1000, 1000, 10), + "category": "floor", + }, + "Floor_300x400": { + "path": f"{MESH_ROOT}/Architecture/Floors/SM_Floor_300x400.SM_Floor_300x400", + "default_size": (300, 400, 10), + "category": "floor", + }, + "Floor_200x300": { + "path": f"{MESH_ROOT}/Architecture/Floors/SM_Floor_200x300.SM_Floor_200x300", + "default_size": (200, 300, 10), + "category": "floor", + }, + # ---- 建筑 — 门 ---- + "RotativeDoor_01": { + "path": f"{MESH_ROOT}/Architecture/Doors/SM_RotativeDoor_01.SM_RotativeDoor_01", + "default_size": None, + "category": "door", + }, + "GarageDoorOpen_01": { + "path": f"{MESH_ROOT}/Architecture/Doors/SM_GarageDoorOpen_01.SM_GarageDoorOpen_01", + "default_size": None, + "category": "door", + }, + # ---- 建筑 — 窗户 ---- + "FakeWindowsFrame": { + "path": f"{MESH_ROOT}/Architecture/WindowsSet/SM_FakeWindowsFrame.SM_FakeWindowsFrame", + "default_size": None, + "category": "window", + }, + # ---- 建筑 — 围栏/围挡 ---- + "BarrierWall_600": { + "path": f"{MESH_ROOT}/Architecture/Barriers/SM_BarrierWall_600.SM_BarrierWall_600", + "default_size": (600, 20, 100), + "category": "barrier", + }, + "BarrierWall_200": { + "path": f"{MESH_ROOT}/Architecture/Barriers/SM_BarrierWall_200.SM_BarrierWall_200", + "default_size": (200, 20, 100), + "category": "barrier", + }, + "Fence_Small_400": { + "path": f"{MESH_ROOT}/Industrials/SM_Fence_Small_400.SM_Fence_Small_400", + "default_size": (400, 5, 100), + "category": "fence", + }, + # ---- 建筑 — 横梁 ---- + "Beam_300": { + "path": f"{MESH_ROOT}/Architecture/Beams/SM_Beam_300.SM_Beam_300", + "default_size": None, + "category": "beam", + }, + # ---- 建筑 — 大型建筑 ---- + "Building_01": { + "path": f"{MESH_ROOT}/BigBuildings/SM_Building_01.SM_Building_01", + "default_size": None, + "category": "building", + }, + # ---- 家具 ---- + "SimpleTable_01": { + "path": f"{MESH_ROOT}/Furnitures/SM_SimpleTable_01.SM_SimpleTable_01", + "default_size": None, + "category": "furniture", + }, + "SimpleTable_02": { + "path": f"{MESH_ROOT}/Furnitures/SM_SimpleTable_02.SM_SimpleTable_02", + "default_size": None, + "category": "furniture", + }, + "BedSingle": { + "path": f"{MESH_ROOT}/Bedroom/SM_BedSingle.SM_BedSingle", + "default_size": None, + "category": "furniture", + }, + "Monitor_01": { + "path": f"{MESH_ROOT}/Furnitures/SM_Monitor_01.SM_Monitor_01", + "default_size": None, + "category": "furniture", + }, + # ---- 工业/装饰 ---- + "Barrel": { + "path": f"{MESH_ROOT}/Industrials/SM_Barrel.SM_Barrel", + "default_size": None, + "category": "industrial", + }, + "WoodenBox_Small": { + "path": f"{MESH_ROOT}/Industrials/SM_WoodenBox_Small.SM_WoodenBox_Small", + "default_size": None, + "category": "industrial", + }, + "WoodenBox_Normal": { + "path": f"{MESH_ROOT}/Industrials/SM_WoodenBox_Normal.SM_WoodenBox_Normal", + "default_size": None, + "category": "industrial", + }, + "WoodenPallet_01": { + "path": f"{MESH_ROOT}/Industrials/SM_WoodenPallet_01.SM_WoodenPallet_01", + "default_size": None, + "category": "industrial", + }, + "Bucket_01": { + "path": f"{MESH_ROOT}/Decorations/SM_Bucket_01.SM_Bucket_01", + "default_size": None, + "category": "industrial", + }, + "TrashCans_01": { + "path": f"{MESH_ROOT}/Trashs/SM_TrashCans_01.SM_TrashCans_01", + "default_size": None, + "category": "industrial", + }, + "Container_Normal": { + "path": f"{MESH_ROOT}/Industrials/SM_Container_Normal.SM_Container_Normal", + "default_size": None, + "category": "industrial", + }, + # ---- 载具 ---- + "Car01": { + "path": f"{MESH_ROOT}/Vehicles/SM_Car01.SM_Car01", + "default_size": None, + "category": "vehicle", + }, + # ---- 基础体 ---- + "Cube": { + "path": f"{MESH_ROOT}/Primitives/SM_Cube.SM_Cube", + "default_size": (100, 100, 100), + "category": "primitive", + }, + "Cylinder": { + "path": f"{MESH_ROOT}/Primitives/SM_Cylinder.SM_Cylinder", + "default_size": (100, 100, 100), + "category": "primitive", + }, + "CirclePlatform": { + "path": f"{MESH_ROOT}/Extra/SM_CirclePlatform.SM_CirclePlatform", + "default_size": None, + "category": "primitive", + }, + # ---- 其他 ---- + "Tree_01": { + "path": f"{MESH_ROOT}/Vegetations/SM_Tree_01.SM_Tree_01", + "default_size": None, + "category": "vegetation", + }, + "RoadLamp_01": { + "path": f"{MESH_ROOT}/Lights/SM_RoadLamp_01.SM_RoadLamp_01", + "default_size": None, + "category": "light_fixture", + }, + "DisplayPanels_400x200": { + "path": f"{MESH_ROOT}/DisplayPanels/SM_DisplayPanels_400x200.SM_DisplayPanels_400x200", + "default_size": None, + "category": "decoration", + }, +} diff --git a/tools/level-builder/config/material_mapping.py b/tools/level-builder/config/material_mapping.py new file mode 100644 index 0000000..ccf511a --- /dev/null +++ b/tools/level-builder/config/material_mapping.py @@ -0,0 +1,25 @@ +"""标识色材质路径映射。 + +数据来源: docs/technical/关卡-v01-搭建指南.md §1.13 +""" + +MATERIAL_PATHS = { + # ---- Basics(标识色) ---- + "MI_DevRed": "/Game/BlockingStarterPack/Materials/Blocking/Basics/MI_DevRed.MI_DevRed", + "MI_DevOrange": "/Game/BlockingStarterPack/Materials/Blocking/Basics/MI_DevOrange.MI_DevOrange", + "MI_DevGray": "/Game/BlockingStarterPack/Materials/Blocking/Basics/MI_DevGray.MI_DevGray", + "MI_DevBrown": "/Game/BlockingStarterPack/Materials/Blocking/Basics/MI_DevBrown.MI_DevBrown", + "MI_DevWhite": "/Game/BlockingStarterPack/Materials/Blocking/Basics/MI_DevWhite.MI_DevWhite", + "MI_DevBlue": "/Game/BlockingStarterPack/Materials/Blocking/Basics/MI_DevBlue.MI_DevBlue", + "MI_DevGreen": "/Game/BlockingStarterPack/Materials/Blocking/Basics/MI_DevGreen.MI_DevGreen", + "MI_DevSkyBlue": "/Game/BlockingStarterPack/Materials/Blocking/Basics/MI_DevSkyBlue.MI_DevSkyBlue", + "MI_DevYellow": "/Game/BlockingStarterPack/Materials/Blocking/Basics/MI_DevYellow.MI_DevYellow", + "MI_DevFoliage": "/Game/BlockingStarterPack/Materials/Blocking/Basics/MI_DevFoliage.MI_DevFoliage", + "MI_DevPink": "/Game/BlockingStarterPack/Materials/Blocking/Basics/MI_DevPink.MI_DevPink", + # ---- Glass ---- + "MI_DevGlassWhite": "/Game/BlockingStarterPack/Materials/Glass/MI_DevGlassWhite.MI_DevGlassWhite", + "MI_DevGlassBlue": "/Game/BlockingStarterPack/Materials/Glass/MI_DevGlassBlue.MI_DevGlassBlue", +} + +# 材质在 Content/ 目录下的文件系统路径前缀(用于离线文件存在性验证) +MATERIAL_FS_PREFIX = "Content/BlockingStarterPack/Materials" diff --git a/tools/level-builder/config/substitution_rules.py b/tools/level-builder/config/substitution_rules.py new file mode 100644 index 0000000..300ecb5 --- /dev/null +++ b/tools/level-builder/config/substitution_rules.py @@ -0,0 +1,36 @@ +"""Primitives 替代规则。 + +数据来源: docs/technical/关卡-v01-搭建报告.md 第四节(缩放记录) + +当搭建指南中直接指定了资产和缩放时,无需查此表。 +此表用于未来执行案解析器,将语义化物件名映射到 Primitives 替代方案。 +""" + +SUBSTITUTION_RULES = { + # ---- 家具/家电 ---- + "冰箱": {"asset": "Cube", "scale": (0.3, 0.3, 1.6), "material": "MI_DevWhite"}, + "冰柜": {"asset": "Cube", "scale": (1.0, 0.6, 0.85), "material": "MI_DevWhite"}, + "电视柜": {"asset": "SimpleTable_02", "scale": (0.85, 0.75, 0.67)}, + # ---- 建筑细节 ---- + "门垫": {"asset": "Cube", "scale": (0.6, 0.4, 0.02), "material": "MI_DevGray"}, + "日历": {"asset": "Cube", "scale": (0.3, 0.02, 0.4), "material": "MI_DevRed"}, + "招牌": {"asset": "Cube", "scale": (3.0, 0.05, 0.4), "material": "MI_DevBlue"}, + "涂鸦": {"asset": "Cube", "scale": (1.2, 0.05, 0.8), "material": "MI_DevYellow"}, + # ---- 玻璃 ---- + "玻璃柜台": {"asset": "Cube", "scale": (2.0, 0.6, 0.9), "material": "MI_DevGlassWhite"}, + "积水坑": {"asset": "Cube", "scale": (1.2, 0.8, 0.01), "material": "MI_DevGlassBlue"}, + # ---- 街道/城郊物件 ---- + "电话亭": {"asset": "Cube", "scale": (0.8, 0.8, 2.2), "material": "MI_DevGray"}, + "电线杆": {"asset": "Cylinder", "scale": (0.04, 0.04, 12.0), "material": "MI_DevGray"}, + "晾衣杆_柱": {"asset": "Cylinder", "scale": (0.05, 0.05, 3.6), "material": "MI_DevGray"}, + "芦苇": {"asset": "Cylinder", "scale": (0.08, 0.08, 2.0), "material": "MI_DevFoliage"}, + "花盆": {"asset": "Cylinder", "scale": (0.2, 0.2, 0.25), "material": "MI_DevGreen"}, + # ---- 水塘 ---- + "荷叶": {"asset": "CirclePlatform", "scale": (0.06, 0.06, 0.01), "material": "MI_DevGreen"}, + "青蛙": {"asset": "Cube", "scale": (0.05, 0.05, 0.04), "material": "MI_DevGreen"}, + "下水道盖": {"asset": "CirclePlatform", "scale": (0.12, 0.12, 0.02), "material": "MI_DevGray"}, + "弹珠圈": {"asset": "CirclePlatform", "scale": (0.16, 0.16, 0.01), "material": "MI_DevGray"}, + # ---- 自然 ---- + "青苔": {"asset": "Cube", "scale": (0.6, 0.4, 0.01), "material": "MI_DevFoliage"}, + "蜘蛛网": {"asset": "Cube", "scale": (0.3, 0.01, 0.3), "material": "MI_DevWhite"}, +} diff --git a/tools/level-builder/config/zone_config.py b/tools/level-builder/config/zone_config.py new file mode 100644 index 0000000..765d8fd --- /dev/null +++ b/tools/level-builder/config/zone_config.py @@ -0,0 +1,142 @@ +"""区域定义、Outliner 文件夹结构、Actor 命名规范。 + +数据来源: + - docs/design/prototype/关卡-v01-城郊小街-执行案.md §二 + - docs/technical/关卡-v01-搭建指南.md §〇 +""" + +# ---- 场景全局参数 ---- +SCENE_PARAMS = { + "scene_size": (8000, 6000), # cm + "ground_z": 0, + "character_height": 120, # cm + "camera_height": 100, # cm + "time_of_day": "15:00", + "origin_corner": "西南角地平面", +} + +# ---- 区域定义 ---- +ZONES = { + "Z1": { + "name": "家", + "name_en": "Home", + "origin": (0, 0, 0), + "bounds": (1000, 800), + "color_material": "MI_DevRed", + }, + "Z2": { + "name": "小卖部", + "name_en": "CornerShop", + "origin": (1000, 200, 0), + "bounds": (600, 600), + "color_material": "MI_DevOrange", + }, + "Z3": { + "name": "主街道", + "name_en": "MainStreet", + "origin": (0, 800, 0), + "bounds": (5000, 500), + "color_material": "MI_DevGray", + }, + "Z4": { + "name": "空地", + "name_en": "VacantLot", + "origin": (3500, 1300, 0), + "bounds": (1500, 1200), + "color_material": "MI_DevBrown", + }, + "Z5": { + "name": "巷子", + "name_en": "Alley", + "origin": (2300, 1300, 0), + "bounds": (300, 2000), + "color_material": "MI_DevWhite", + }, + "Z6": { + "name": "水塘边", + "name_en": "Pond", + "origin": (1600, 3300, 0), + "bounds": (1500, 1400), + "color_material": "MI_DevSkyBlue", + }, + "Z7": { + "name": "老居民楼", + "name_en": "OldBuilding", + "origin": (5800, 200, 0), + "bounds": (1200, 1800), + "color_material": "MI_DevGray", + }, +} + +# ---- Outliner 文件夹结构 ---- +LEVEL_NAME = "LVL_SuburbanV01" + +ZONE_FOLDERS = { + "Z1": f"{LEVEL_NAME}/Z1_家", + "Z2": f"{LEVEL_NAME}/Z2_小卖部", + "Z3": f"{LEVEL_NAME}/Z3_主街道", + "Z4": f"{LEVEL_NAME}/Z4_空地", + "Z5": f"{LEVEL_NAME}/Z5_巷子", + "Z6": f"{LEVEL_NAME}/Z6_水塘边", + "Z7": f"{LEVEL_NAME}/Z7_老居民楼", + "GLOBAL": f"{LEVEL_NAME}/Global", +} + +CATEGORY_FOLDERS = { + "STR": "Structure", + "PROP": "Props", + "INTR": "Interactables", + "COLL": "Collectibles", + "BND": "Boundaries", + "LGT": "Lighting", +} + +GLOBAL_SUBFOLDERS = { + "BND": f"{LEVEL_NAME}/Global/Boundaries", + "LGT": f"{LEVEL_NAME}/Global/Lighting", + "PLAY": f"{LEVEL_NAME}/Global/PlayerStart", +} + + +def get_folder_path(zone_id: str, category: str) -> str: + """根据区域 ID 和类别获取 Outliner 文件夹路径。""" + if zone_id == "GLOBAL": + return GLOBAL_SUBFOLDERS.get(category, f"{LEVEL_NAME}/Global") + base = ZONE_FOLDERS.get(zone_id, f"{LEVEL_NAME}/Global") + sub = CATEGORY_FOLDERS.get(category, "") + if sub: + return f"{base}/{sub}" + return base + + +# ---- Actor 命名模板 ---- +# LVL___ +# 已在搭建指南中给出完整名称,脚本直接使用。 + + +# ---- 搭建顺序 ---- +BUILD_ORDER = ["Z1", "Z3", "Z2", "Z4", "Z5", "Z6", "Z7"] + +# ---- Player Start ---- +PLAYER_START = { + "location": (500, 720, 0), + "rotation": (0, 0, 0), # 面向 +Y(北) +} + +# ---- 光照 ---- +LIGHTING = { + "directional_light": { + "location": (0, 0, 500), + "rotation": (-45, 45, 0), # 从西南照射,仰角45° + "intensity": 3.0, + "color": (1.0, 0.95, 0.85), # 暖白 + }, + "sky_light": { + "intensity": 0.5, + }, + "street_lights": [ + {"location": (1500, 1050, 0), "intensity": 0.3}, + {"location": (3000, 1050, 0), "intensity": 0.3}, + {"location": (4500, 1050, 0), "intensity": 0.3}, + ], +} diff --git a/tools/level-builder/main.py b/tools/level-builder/main.py new file mode 100644 index 0000000..a31f43c --- /dev/null +++ b/tools/level-builder/main.py @@ -0,0 +1,199 @@ +"""Level Builder CLI — 白模关卡自动生成工具。 + +用法: + # Stage 1: 解析搭建指南 → JSON + python main.py parse --input ../../docs/technical/关卡-v01-搭建指南.md --output output/level_v01.json + + # Stage 1.5: 验证 + python main.py validate --input output/level_v01.json [--project-root ../..] + + # Stage 2: UE5 编辑器内构建(需在编辑器 Python 环境中运行) + # 方式 A: 在 Output Log Python 控制台: + # exec(open(r"tools/level-builder/main.py").read()) + # main(["build", "--input", "output/level_v01.json"]) + # 方式 B: File > Execute Python Script + + # Stage 3: 生成报告 + python main.py report --input output/level_v01.json [--build-log output/build_log.json] --output report.md +""" + +import argparse +import json +import logging +import sys +from pathlib import Path + +# 将项目 tools 目录加入 sys.path +_TOOLS_DIR = Path(__file__).resolve().parent +_LEVEL_BUILDER_DIR = _TOOLS_DIR +_PROJECT_ROOT = _TOOLS_DIR.parent.parent + +if str(_TOOLS_DIR) not in sys.path: + sys.path.insert(0, str(_TOOLS_DIR)) +if str(_PROJECT_ROOT) not in sys.path: + sys.path.insert(0, str(_PROJECT_ROOT)) + +# 配置日志 +logging.basicConfig( + level=logging.INFO, + format="[%(levelname)s] %(name)s: %(message)s", +) +logger = logging.getLogger("level_builder") + + +def cmd_parse(args): + """解析搭建指南 Markdown → JSON。""" + from parsers.build_guide_parser import BuildGuideParser + + input_path = args.input + output_path = args.output or "output/level_data.json" + + logger.info(f"解析搭建指南: {input_path}") + + parser = BuildGuideParser() + data = parser.parse_file(input_path) + + # 写入 JSON + out_path = Path(output_path) + out_path.parent.mkdir(parents=True, exist_ok=True) + with open(out_path, "w", encoding="utf-8") as f: + json.dump(data, f, ensure_ascii=False, indent=2) + + summary = data.get("summary", {}) + logger.info(f"解析完成: {summary.get('total_actors', 0)} 个 Actor") + logger.info(f" 按类别: {summary.get('by_category', {})}") + logger.info(f" 按区域: {summary.get('by_zone', {})}") + logger.info(f" 唯一资产数: {summary.get('unique_assets', 0)}") + logger.info(f"输出: {out_path.resolve()}") + + +def cmd_validate(args): + """验证 JSON 数据中的资产引用。""" + from validation.asset_validator import validate_actors + + input_path = args.input + project_root = args.project_root or str(_PROJECT_ROOT) + + logger.info(f"验证: {input_path}") + + with open(input_path, "r", encoding="utf-8") as f: + data = json.load(f) + + actors = data.get("actors", []) + result = validate_actors(actors, project_root) + + if result.is_valid: + logger.info("✅ 验证通过!") + else: + logger.error(f"❌ 验证失败: {len(result.errors)} 个错误") + for err in result.errors: + logger.error(f" {err}") + + if result.warnings: + for warn in result.warnings: + logger.warning(f" {warn}") + + logger.info(f"有效 Actor: {result.valid_actors}/{result.total_actors}") + + # 保存验证结果 + output_path = Path(input_path).parent / "validation_result.json" + with open(output_path, "w", encoding="utf-8") as f: + json.dump({ + "is_valid": result.is_valid, + "total": result.total_actors, + "valid": result.valid_actors, + "errors": result.errors, + "warnings": result.warnings, + "missing_assets": sorted(result.missing_assets), + "missing_materials": sorted(result.missing_materials), + }, f, ensure_ascii=False, indent=2) + logger.info(f"验证结果: {output_path}") + + +def cmd_build(args): + """在 UE5 编辑器中构建关卡。""" + try: + from builder.scene_builder import build_level + except ImportError: + print("[错误] 无法导入 builder 模块。确保在 UE5 编辑器 Python 环境中运行。") + print(" 在 Output Log 中切换到 Python,然后执行:") + print(f' exec(open(r"{Path(__file__).resolve()}").read())') + print(f' build_level(r"{Path(args.input).resolve()}")') + return + + zones = args.zones.split(",") if args.zones else None + build_level(args.input, clear_existing=args.clear, zones=zones) + + +def cmd_report(args): + """生成搭建报告。""" + from report.report_generator import generate_report + + input_path = args.input + output_path = args.output or "output/搭建报告.md" + build_log_path = args.build_log + + logger.info(f"生成报告: {input_path}") + + with open(input_path, "r", encoding="utf-8") as f: + data = json.load(f) + + build_log = None + if build_log_path: + try: + with open(build_log_path, "r", encoding="utf-8") as f: + build_log = json.load(f) + except FileNotFoundError: + logger.warning(f"构建日志不存在: {build_log_path},生成无状态报告") + + report = generate_report(data, build_log, output_path) + logger.info(f"报告已生成: {output_path}") + + +def main(argv=None): + """CLI 入口。""" + parser = argparse.ArgumentParser( + description="ChildHood 白模关卡自动生成工具", + prog="level-builder", + ) + subparsers = parser.add_subparsers(dest="command", help="子命令") + + # parse + p_parse = subparsers.add_parser("parse", help="解析搭建指南 Markdown → JSON") + p_parse.add_argument("--input", "-i", required=True, help="搭建指南 Markdown 文件路径") + p_parse.add_argument("--output", "-o", default="output/level_data.json", help="输出 JSON 路径") + + # validate + p_validate = subparsers.add_parser("validate", help="验证 JSON 数据") + p_validate.add_argument("--input", "-i", required=True, help="JSON 文件路径") + p_validate.add_argument("--project-root", "-r", help="项目根目录(用于文件存在性检查)") + + # build + p_build = subparsers.add_parser("build", help="在 UE5 中构建关卡") + p_build.add_argument("--input", "-i", required=True, help="JSON 文件路径") + p_build.add_argument("--clear", action="store_true", default=True, help="清除已有 LVL_* Actor") + p_build.add_argument("--no-clear", dest="clear", action="store_false", help="不清除已有 Actor") + p_build.add_argument("--zones", "-z", help="仅构建指定区域,逗号分隔(如 Z1,Z3)") + + # report + p_report = subparsers.add_parser("report", help="生成搭建报告") + p_report.add_argument("--input", "-i", required=True, help="JSON 文件路径") + p_report.add_argument("--build-log", "-l", help="构建日志 JSON 路径") + p_report.add_argument("--output", "-o", default="output/搭建报告.md", help="报告输出路径") + + args = parser.parse_args(argv) + + if args.command == "parse": + cmd_parse(args) + elif args.command == "validate": + cmd_validate(args) + elif args.command == "build": + cmd_build(args) + elif args.command == "report": + cmd_report(args) + else: + parser.print_help() + + +if __name__ == "__main__": + main() diff --git a/tools/level-builder/output/level_v01.json b/tools/level-builder/output/level_v01.json new file mode 100644 index 0000000..9847a06 --- /dev/null +++ b/tools/level-builder/output/level_v01.json @@ -0,0 +1,7761 @@ +{ + "metadata": { + "source": "关卡-v01-搭建指南.md", + "scene_size": [ + 8000, + 6000 + ], + "ground_z": 0, + "character_height": 120, + "camera_height": 100 + }, + "actors": [ + { + "actor_name": "LVL_Z1_STR_Floor", + "asset_key": "Floor_1000x1000", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 500.0, + 400.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 0.8, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_STR_Floor", + "asset_key": "Floor_1000x1000", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z2", + "location": [ + 1300.0, + 500.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.6, + 0.6, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z2_小卖部/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_STR_Floor_01", + "asset_key": "Floor_1000x1000", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 500.0, + 1050.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 0.5, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_STR_Floor_02", + "asset_key": "Floor_1000x1000", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 1500.0, + 1050.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 0.5, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_STR_Floor_03", + "asset_key": "Floor_1000x1000", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 2500.0, + 1050.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 0.5, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_STR_Floor_04", + "asset_key": "Floor_1000x1000", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 3500.0, + 1050.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 0.5, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_STR_Floor_05", + "asset_key": "Floor_1000x1000", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 4500.0, + 1050.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 0.5, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z4_STR_Floor_01", + "asset_key": "Floor_1000x1000", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z4", + "location": [ + 4000.0, + 1800.0, + 10.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.5, + 1.2, + 1.0 + ], + "material": "MI_DevBrown", + "folder": "LVL_SuburbanV01/Z4_空地/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z5_STR_Floor_01", + "asset_key": "Floor_1000x1000", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z5", + "location": [ + 2450.0, + 1800.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.3, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z5_巷子/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z5_STR_Floor_02", + "asset_key": "Floor_1000x1000", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z5", + "location": [ + 2450.0, + 2800.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.3, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z5_巷子/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z6_STR_GroundSouth", + "asset_key": "Floor_1000x1000", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z6", + "location": [ + 2350.0, + 3475.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.5, + 0.35, + 1.0 + ], + "material": "MI_DevBrown", + "folder": "LVL_SuburbanV01/Z6_水塘边/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z6_STR_GroundEast", + "asset_key": "Floor_1000x1000", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z6", + "location": [ + 3075.0, + 4000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.15, + 0.8, + 1.0 + ], + "material": "MI_DevBrown", + "folder": "LVL_SuburbanV01/Z6_水塘边/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z6_STR_GroundWest", + "asset_key": "Floor_1000x1000", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z6", + "location": [ + 1675.0, + 4000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.15, + 0.8, + 1.0 + ], + "material": "MI_DevBrown", + "folder": "LVL_SuburbanV01/Z6_水塘边/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z6_STR_Water", + "asset_key": "Floor_1000x1000", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z6", + "location": [ + 2350.0, + 4000.0, + -20.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.2, + 0.8, + 0.5 + ], + "material": "MI_DevSkyBlue", + "folder": "LVL_SuburbanV01/Z6_水塘边/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_01", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 0.0, + 200.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_02", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 0.0, + 600.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_03", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 0.0, + 1000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_04", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 0.0, + 1400.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_05", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 0.0, + 1800.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_06", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 0.0, + 2200.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_07", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 0.0, + 2600.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_08", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 0.0, + 3000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_09", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 0.0, + 3400.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_10", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 0.0, + 3800.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_11", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 0.0, + 4200.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_12", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 0.0, + 4600.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_13", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 0.0, + 5000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_14", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 0.0, + 5400.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_15", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 0.0, + 5800.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_East_01~15", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 0.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_North_01~20", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 0.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_01", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 1900.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_02", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 2500.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_03", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 3100.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_04", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 3700.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_05", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 4300.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_06", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 4900.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_07", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 5500.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_08", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 6100.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_09", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 6700.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_10", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 7300.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_11", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 7900.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_01", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 0.0, + 200.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_02", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 0.0, + 600.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_03", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 0.0, + 1000.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_04", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 0.0, + 1400.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_05", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 0.0, + 1800.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_06", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 0.0, + 2200.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_07", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 0.0, + 2600.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_08", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 0.0, + 3000.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_09", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 0.0, + 3400.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_10", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 0.0, + 3800.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_11", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 0.0, + 4200.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_12", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 0.0, + 4600.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_13", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 0.0, + 5000.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_14", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 0.0, + 5400.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_West_15", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 0.0, + 5800.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_East_01", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 8000.0, + 200.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_East_02", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 8000.0, + 600.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_East_03", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 8000.0, + 1000.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_East_04", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 8000.0, + 1400.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_East_05", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 8000.0, + 1800.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_East_06", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 8000.0, + 2200.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_East_07", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 8000.0, + 2600.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_East_08", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 8000.0, + 3000.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_East_09", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 8000.0, + 3400.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_East_10", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 8000.0, + 3800.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_East_11", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 8000.0, + 4200.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_East_12", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 8000.0, + 4600.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_East_13", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 8000.0, + 5000.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_East_14", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 8000.0, + 5400.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_East_15", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 8000.0, + 5800.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_North_01", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 200.0, + 6000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_North_02", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 600.0, + 6000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_North_03", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 1000.0, + 6000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_North_04", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 1400.0, + 6000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_North_05", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 1800.0, + 6000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_North_06", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 2200.0, + 6000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_North_07", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 2600.0, + 6000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_North_08", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 3000.0, + 6000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_North_09", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 3400.0, + 6000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_North_10", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 3800.0, + 6000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_North_11", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 4200.0, + 6000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_North_12", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 4600.0, + 6000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_North_13", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 5000.0, + 6000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_North_14", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 5400.0, + 6000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_North_15", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 5800.0, + 6000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_North_16", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 6200.0, + 6000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_North_17", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 6600.0, + 6000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_North_18", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 7000.0, + 6000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_North_19", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 7400.0, + 6000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_North_20", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 7800.0, + 6000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_01", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 1900.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_02", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 2500.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_03", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 3100.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_04", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 3700.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_05", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 4300.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_06", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 4900.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_07", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 5500.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_08", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 6100.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_09", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 6700.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_10", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 7300.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_BND_South_11", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "BND", + "zone_id": "GLOBAL", + "location": [ + 7900.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Global/Boundaries", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_STR_SouthWall_01", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 200.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_STR_SouthWall_02", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 600.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_STR_WestWall_01", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 0.0, + 200.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_STR_WestWall_02", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 0.0, + 600.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_STR_EastWall_01", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 980.0, + 200.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_STR_EastWall_02", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 980.0, + 600.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_STR_NorthWall_West", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 200.0, + 780.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_STR_NorthWall_Gate", + "asset_key": "WallDoor_200x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 500.0, + 780.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_STR_NorthWall_East", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 800.0, + 780.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_STR_GateDoor", + "asset_key": "RotativeDoor_01", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 500.0, + 780.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGreen", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_STR_HouseSouthWall", + "asset_key": "WallWindow_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 400.0, + 30.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_STR_HouseSouthWin", + "asset_key": "WallWindowSmall_200x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 600.0, + 30.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_STR_HouseWestWall", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 200.0, + 220.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_STR_HouseWestTop", + "asset_key": "Wall_400x100", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 200.0, + 220.0, + 300.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_STR_HouseEastWall", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 780.0, + 220.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_STR_HouseEastTop", + "asset_key": "Wall_400x100", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 780.0, + 220.0, + 300.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_STR_HouseNorthWall", + "asset_key": "WallDoor_200x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 400.0, + 410.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_STR_HouseNorthFill", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 600.0, + 410.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_STR_HouseRoof_01", + "asset_key": "Floor_300x400", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 350.0, + 230.0, + 280.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBrown", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_STR_HouseRoof_02", + "asset_key": "Floor_300x400", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 650.0, + 230.0, + 280.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBrown", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_STR_CourtyardFloor", + "asset_key": "Floor_1000x1000", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z1", + "location": [ + 500.0, + 400.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 0.8, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z1_家/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_PROP_OldBicycle", + "asset_key": "Car01", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z1", + "location": [ + 100.0, + 650.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.2, + 0.2, + 0.2 + ], + "material": "", + "folder": "LVL_SuburbanV01/Z1_家/Props", + "note": "50%缩放,靠西院墙", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_PROP_ClothesPole_Beam", + "asset_key": "Beam_300", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z1", + "location": [ + 500.0, + 600.0, + 180.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z1_家/Props", + "note": "横杆", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_PROP_ClothesPole_Pole1", + "asset_key": "Cylinder", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z1", + "location": [ + 380.0, + 600.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.05, + 0.05, + 3.6 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z1_家/Props", + "note": "支撑柱", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_PROP_ClothesPole_Pole2", + "asset_key": "Cylinder", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z1", + "location": [ + 620.0, + 600.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.05, + 0.05, + 3.6 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z1_家/Props", + "note": "支撑柱", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_PROP_JunkPile_Box1", + "asset_key": "WoodenBox_Small", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z1", + "location": [ + 850.0, + 100.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "", + "folder": "LVL_SuburbanV01/Z1_家/Props", + "note": "东南角", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_PROP_JunkPile_Box2", + "asset_key": "WoodenBox_Small", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z1", + "location": [ + 870.0, + 120.0, + 35.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "", + "folder": "LVL_SuburbanV01/Z1_家/Props", + "note": "叠放在上方", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_PROP_JunkPile_Bucket", + "asset_key": "Bucket_01", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z1", + "location": [ + 890.0, + 80.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "", + "folder": "LVL_SuburbanV01/Z1_家/Props", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_PROP_DoorMat", + "asset_key": "Cube", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z1", + "location": [ + 480.0, + 740.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.6, + 0.4, + 0.02 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z1_家/Props", + "note": "扁薄长方体", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_PROP_Fridge", + "asset_key": "Barrel", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z1", + "location": [ + 720.0, + 80.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.3, + 0.3, + 1.6 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z1_家/Props", + "note": "竖放,缩放模拟冰箱", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_PROP_TV", + "asset_key": "Monitor_01", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z1", + "location": [ + 320.0, + 80.0, + 45.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z1_家/Props", + "note": "房屋内书桌上", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_PROP_Desk", + "asset_key": "SimpleTable_01", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z1", + "location": [ + 300.0, + 70.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "", + "folder": "LVL_SuburbanV01/Z1_家/Props", + "note": "房屋内靠西墙", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_PROP_Bed", + "asset_key": "BedSingle", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z1", + "location": [ + 350.0, + 250.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "", + "folder": "LVL_SuburbanV01/Z1_家/Props", + "note": "房屋内中部偏南", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_PROP_Calendar", + "asset_key": "Cube", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z1", + "location": [ + 500.0, + 40.0, + 180.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.3, + 0.02, + 0.4 + ], + "material": "MI_DevRed", + "folder": "LVL_SuburbanV01/Z1_家/Props", + "note": "薄片挂墙", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_PROP_TVStand", + "asset_key": "SimpleTable_02", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z1", + "location": [ + 320.0, + 55.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.85, + 0.75, + 0.67 + ], + "material": "", + "folder": "LVL_SuburbanV01/Z1_家/Props", + "note": "电视柜,缩放至约 85×45×50cm", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z1_INTR_01_Fridge", + "asset_key": "Cube", + "asset_type": "static_mesh", + "category": "INTR", + "zone_id": "Z1", + "location": [ + 720.0, + 80.0, + 80.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.3, + 0.3, + 0.3 + ], + "material": "MI_DevYellow", + "folder": "LVL_SuburbanV01/Z1_家/Interactables", + "note": "交互物占位标记", + "trigger_radius": 150.0, + "interact_type": "观察", + "rarity": "", + "source_ref": "interaction #1" + }, + { + "actor_name": "LVL_Z1_INTR_02_Gate", + "asset_key": "Cube", + "asset_type": "static_mesh", + "category": "INTR", + "zone_id": "Z1", + "location": [ + 500.0, + 780.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.3, + 0.3, + 0.3 + ], + "material": "MI_DevYellow", + "folder": "LVL_SuburbanV01/Z1_家/Interactables", + "note": "交互物占位标记", + "trigger_radius": 150.0, + "interact_type": "操作(门)", + "rarity": "", + "source_ref": "interaction #2" + }, + { + "actor_name": "LVL_Z1_INTR_06_TV", + "asset_key": "Cube", + "asset_type": "static_mesh", + "category": "INTR", + "zone_id": "Z1", + "location": [ + 320.0, + 80.0, + 70.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.3, + 0.3, + 0.3 + ], + "material": "MI_DevYellow", + "folder": "LVL_SuburbanV01/Z1_家/Interactables", + "note": "交互物占位标记", + "trigger_radius": 150.0, + "interact_type": "观察", + "rarity": "", + "source_ref": "interaction #6" + }, + { + "actor_name": "LVL_Z1_COLL_10_CatEyeMarble", + "asset_key": "CirclePlatform", + "asset_type": "static_mesh", + "category": "COLL", + "zone_id": "Z1", + "location": [ + 870.0, + 140.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.03, + 0.03, + 0.03 + ], + "material": "MI_DevYellow", + "folder": "LVL_SuburbanV01/Z1_家/Collectibles", + "note": "收集品占位标记", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "稀有", + "source_ref": "collection #10" + }, + { + "actor_name": "LVL_Z3_STR_SouthWall_C1", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 1800.0, + 800.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_STR_SouthWall_C2", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 2200.0, + 800.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_STR_SouthWall_C3", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 2600.0, + 800.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_STR_SouthWall_C4", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 3000.0, + 800.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_STR_SouthWall_C5", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 3400.0, + 800.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_STR_SouthWall_C6", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 3800.0, + 800.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_STR_SouthWall_D1", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 4200.0, + 800.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_STR_SouthWall_D2", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 4600.0, + 800.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_STR_NorthWall_A1", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 200.0, + 1300.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_STR_NorthWall_A2", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 600.0, + 1300.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_STR_NorthWall_A3", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 1000.0, + 1300.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_STR_NorthWall_A4", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 1400.0, + 1300.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_STR_NorthWall_A5", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 1800.0, + 1300.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_STR_NorthWall_A6", + "asset_key": "Wall_200x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 2100.0, + 1300.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_STR_NorthWall_C1", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 2800.0, + 1300.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_STR_NorthWall_C2", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 3200.0, + 1300.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_STR_NorthWall_C3", + "asset_key": "Wall_100x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z3", + "location": [ + 3450.0, + 1300.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_PROP_PhoneBooth", + "asset_key": "Cube", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z3", + "location": [ + 1800.0, + 380.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.8, + 0.8, + 2.2 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Props", + "note": "街道北侧靠墙", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_PROP_Bicycle", + "asset_key": "Car01", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z3", + "location": [ + 2800.0, + 880.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.2, + 0.2, + 0.2 + ], + "material": "", + "folder": "LVL_SuburbanV01/Z3_主街道/Props", + "note": "街道南侧", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_PROP_ClothesPole", + "asset_key": "Beam_300", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z3", + "location": [ + 1200.0, + 1250.0, + 180.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z3_主街道/Props", + "note": "北墙处晾衣杆", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_PROP_ClothesPolePole", + "asset_key": "Cylinder", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z3", + "location": [ + 1200.0, + 1250.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.05, + 0.05, + 3.6 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Props", + "note": "支撑柱", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_PROP_SewerCover", + "asset_key": "CirclePlatform", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z3", + "location": [ + 800.0, + 1050.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.12, + 0.12, + 0.02 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Props", + "note": "路面中央", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_PROP_Graffiti", + "asset_key": "Cube", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z3", + "location": [ + 3200.0, + 1270.0, + 100.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.2, + 0.05, + 0.8 + ], + "material": "MI_DevYellow", + "folder": "LVL_SuburbanV01/Z3_主街道/Props", + "note": "北墙C段墙面", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3 PROP_AdWall", + "asset_key": "DisplayPanels_400x200", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z3", + "location": [ + 3800.0, + 1280.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Props", + "note": "北墙D段手绘广告", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_PROP_TrashCan", + "asset_key": "TrashCans_01", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z3", + "location": [ + 4200.0, + 850.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGreen", + "folder": "LVL_SuburbanV01/Z3_主街道/Props", + "note": "街道南侧", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_PROP_PoleWest", + "asset_key": "Cylinder", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z3", + "location": [ + 1000.0, + 1050.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.04, + 0.04, + 12.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Props", + "note": "电线杆西", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_PROP_PoleEast", + "asset_key": "Cylinder", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z3", + "location": [ + 3500.0, + 1050.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.04, + 0.04, + 12.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z3_主街道/Props", + "note": "电线杆东", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_INTR_04_PhoneBooth", + "asset_key": "Cube", + "asset_type": "static_mesh", + "category": "INTR", + "zone_id": "Z3", + "location": [ + 1800.0, + 380.0, + 110.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.3, + 0.3, + 0.3 + ], + "material": "MI_DevYellow", + "folder": "LVL_SuburbanV01/Z3_主街道/Interactables", + "note": "交互物占位标记", + "trigger_radius": 150.0, + "interact_type": "", + "rarity": "", + "source_ref": "interaction #4" + }, + { + "actor_name": "LVL_Z3_INTR_09_Graffiti", + "asset_key": "Cube", + "asset_type": "static_mesh", + "category": "INTR", + "zone_id": "Z3", + "location": [ + 3200.0, + 1270.0, + 140.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.3, + 0.3, + 0.3 + ], + "material": "MI_DevYellow", + "folder": "LVL_SuburbanV01/Z3_主街道/Interactables", + "note": "交互物占位标记", + "trigger_radius": 150.0, + "interact_type": "", + "rarity": "", + "source_ref": "interaction #9" + }, + { + "actor_name": "LVL_Z3_COLL_08_IceFlowerMarble", + "asset_key": "CirclePlatform", + "asset_type": "static_mesh", + "category": "COLL", + "zone_id": "Z3", + "location": [ + 820.0, + 1060.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.03, + 0.03, + 0.03 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z3_主街道/Collectibles", + "note": "收集品占位标记", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "普通", + "source_ref": "collection #8" + }, + { + "actor_name": "LVL_Z2_STR_SouthWall", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z2", + "location": [ + 1200.0, + 200.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevOrange", + "folder": "LVL_SuburbanV01/Z2_小卖部/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_STR_SouthWall2", + "asset_key": "Wall_200x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z2", + "location": [ + 1500.0, + 200.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevOrange", + "folder": "LVL_SuburbanV01/Z2_小卖部/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_STR_WestWall", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z2", + "location": [ + 1000.0, + 400.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevOrange", + "folder": "LVL_SuburbanV01/Z2_小卖部/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_STR_WestWallTop", + "asset_key": "Wall_400x100", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z2", + "location": [ + 1000.0, + 400.0, + 300.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevOrange", + "folder": "LVL_SuburbanV01/Z2_小卖部/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_STR_EastWall", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z2", + "location": [ + 1580.0, + 400.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevOrange", + "folder": "LVL_SuburbanV01/Z2_小卖部/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_STR_EastWallTop", + "asset_key": "Wall_400x100", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z2", + "location": [ + 1580.0, + 400.0, + 300.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevOrange", + "folder": "LVL_SuburbanV01/Z2_小卖部/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_STR_NorthWall_West", + "asset_key": "Wall_200x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z2", + "location": [ + 1100.0, + 580.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevOrange", + "folder": "LVL_SuburbanV01/Z2_小卖部/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_STR_NorthWall_Garage", + "asset_key": "WallDoorGarage_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z2", + "location": [ + 1300.0, + 580.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevOrange", + "folder": "LVL_SuburbanV01/Z2_小卖部/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_STR_NorthWall_East", + "asset_key": "Wall_200x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z2", + "location": [ + 1500.0, + 580.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevOrange", + "folder": "LVL_SuburbanV01/Z2_小卖部/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_STR_GarageDoor", + "asset_key": "GarageDoorOpen_01", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z2", + "location": [ + 1300.0, + 580.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z2_小卖部/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_STR_Roof_01", + "asset_key": "Floor_300x400", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z2", + "location": [ + 1250.0, + 400.0, + 280.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBrown", + "folder": "LVL_SuburbanV01/Z2_小卖部/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_STR_Roof_02", + "asset_key": "Floor_300x400", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z2", + "location": [ + 1350.0, + 400.0, + 280.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBrown", + "folder": "LVL_SuburbanV01/Z2_小卖部/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_STR_Awning_01", + "asset_key": "Floor_200x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z2", + "location": [ + 1100.0, + 700.0, + 260.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z2_小卖部/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_STR_Awning_02", + "asset_key": "Floor_200x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z2", + "location": [ + 1400.0, + 700.0, + 260.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z2_小卖部/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_PROP_Counter", + "asset_key": "Cube", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z2", + "location": [ + 1200.0, + 500.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 2.0, + 0.6, + 0.9 + ], + "material": "MI_DevGlassWhite", + "folder": "LVL_SuburbanV01/Z2_小卖部/Props", + "note": "玻璃柜台", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_PROP_ShelfEast_01", + "asset_key": "Fence_Small_400", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z2", + "location": [ + 1520.0, + 300.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.8 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z2_小卖部/Props", + "note": "东墙货架(竖放)", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_PROP_ShelfEast_02", + "asset_key": "Fence_Small_400", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z2", + "location": [ + 1520.0, + 300.0, + 180.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.8 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z2_小卖部/Props", + "note": "二层", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_PROP_ShelfSouth", + "asset_key": "Fence_Small_400", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z2", + "location": [ + 1100.0, + 230.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.8 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z2_小卖部/Props", + "note": "南墙货架", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_PROP_Freezer", + "asset_key": "Container_Normal", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z2", + "location": [ + 1050.0, + 400.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.25, + 0.15, + 0.4 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z2_小卖部/Props", + "note": "老式冰柜", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_PROP_SmallTV", + "asset_key": "Monitor_01", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z2", + "location": [ + 1350.0, + 540.0, + 90.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.6, + 0.6, + 0.6 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z2_小卖部/Props", + "note": "柜台角落", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_PROP_Signboard", + "asset_key": "Cube", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z2", + "location": [ + 1150.0, + 610.0, + 280.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 3.0, + 0.05, + 0.4 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z2_小卖部/Props", + "note": "招牌", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_PROP_CardRack", + "asset_key": "Cube", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z2", + "location": [ + 1400.0, + 550.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.4, + 0.2, + 0.3 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z2_小卖部/Props", + "note": "卡片架", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z2_INTR_05_ShopOwner", + "asset_key": "Cube", + "asset_type": "static_mesh", + "category": "INTR", + "zone_id": "Z2", + "location": [ + 1300.0, + 480.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.3, + 0.3, + 0.3 + ], + "material": "MI_DevYellow", + "folder": "LVL_SuburbanV01/Z2_小卖部/Interactables", + "note": "交互物占位标记", + "trigger_radius": 200.0, + "interact_type": "", + "rarity": "", + "source_ref": "interaction #5" + }, + { + "actor_name": "LVL_Z2_INTR_07_SnackShelf", + "asset_key": "Cube", + "asset_type": "static_mesh", + "category": "INTR", + "zone_id": "Z2", + "location": [ + 1520.0, + 350.0, + 90.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.3, + 0.3, + 0.3 + ], + "material": "MI_DevYellow", + "folder": "LVL_SuburbanV01/Z2_小卖部/Interactables", + "note": "交互物占位标记", + "trigger_radius": 150.0, + "interact_type": "", + "rarity": "", + "source_ref": "interaction #7" + }, + { + "actor_name": "LVL_Z2_COLL_09_BouncyBall", + "asset_key": "CirclePlatform", + "asset_type": "static_mesh", + "category": "COLL", + "zone_id": "Z2", + "location": [ + 1300.0, + 700.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.03, + 0.03, + 0.03 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z2_小卖部/Collectibles", + "note": "收集品占位标记", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "普通", + "source_ref": "collection #9" + }, + { + "actor_name": "LVL_Z4_STR_EastBound_01", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z4", + "location": [ + 4980.0, + 1600.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z4_空地/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z4_STR_EastBound_02", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z4", + "location": [ + 4980.0, + 2200.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z4_空地/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z4_STR_NorthBound_01", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z4", + "location": [ + 3800.0, + 2480.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z4_空地/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z4_STR_NorthBound_02", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z4", + "location": [ + 4400.0, + 2480.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z4_空地/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z4_STR_NorthBound_03", + "asset_key": "BarrierWall_200", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z4", + "location": [ + 4700.0, + 2480.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z4_空地/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z4_STR_WestLowWall_01", + "asset_key": "BarrierWall_200", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z4", + "location": [ + 3500.0, + 1500.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z4_空地/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z4_STR_WestLowWall_02", + "asset_key": "BarrierWall_200", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z4", + "location": [ + 3500.0, + 1900.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z4_空地/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z4_STR_WestLowWall_03", + "asset_key": "BarrierWall_200", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z4", + "location": [ + 3500.0, + 2300.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z4_空地/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z4_PROP_BigTree", + "asset_key": "Tree_01", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z4", + "location": [ + 4250.0, + 1900.0, + 10.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.2, + 1.2, + 1.2 + ], + "material": "MI_DevFoliage", + "folder": "LVL_SuburbanV01/Z4_空地/Props", + "note": "中央偏北", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z4_PROP_Bricks_01~05", + "asset_key": "WoodenBox_Small", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z4", + "location": [ + 0.0, + 0.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "", + "folder": "LVL_SuburbanV01/Z4_空地/Props", + "note": "5 块散落", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z4_PROP_Puddle", + "asset_key": "Cube", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z4", + "location": [ + 4600.0, + 1500.0, + 5.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.2, + 0.8, + 0.01 + ], + "material": "MI_DevGlassBlue", + "folder": "LVL_SuburbanV01/Z4_空地/Props", + "note": "积水坑", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z4_PROP_MarbleCircle", + "asset_key": "CirclePlatform", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z4", + "location": [ + 4100.0, + 1800.0, + 12.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.16, + 0.16, + 0.01 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z4_空地/Props", + "note": "弹珠圈痕迹", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z4_PROP_Debris_01", + "asset_key": "WoodenPallet_01", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z4", + "location": [ + 4800.0, + 2300.0, + 10.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "", + "folder": "LVL_SuburbanV01/Z4_空地/Props", + "note": "废弃建材", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z4_PROP_Debris_02", + "asset_key": "WoodenBox_Normal", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z4", + "location": [ + 4850.0, + 2250.0, + 10.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "", + "folder": "LVL_SuburbanV01/Z4_空地/Props", + "note": "废弃建材", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z4_INTR_03_BlueMarble", + "asset_key": "Cube", + "asset_type": "static_mesh", + "category": "INTR", + "zone_id": "Z4", + "location": [ + 3900.0, + 1700.0, + 10.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.3, + 0.3, + 0.3 + ], + "material": "MI_DevYellow", + "folder": "LVL_SuburbanV01/Z4_空地/Interactables", + "note": "交互物占位标记", + "trigger_radius": 100.0, + "interact_type": "", + "rarity": "", + "source_ref": "interaction #3 ↔ collection #1" + }, + { + "actor_name": "LVL_Z4_INTR_08_SmallStone", + "asset_key": "Cube", + "asset_type": "static_mesh", + "category": "INTR", + "zone_id": "Z4", + "location": [ + 4550.0, + 1550.0, + 10.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.3, + 0.3, + 0.3 + ], + "material": "MI_DevYellow", + "folder": "LVL_SuburbanV01/Z4_空地/Interactables", + "note": "交互物占位标记", + "trigger_radius": 100.0, + "interact_type": "", + "rarity": "", + "source_ref": "interaction #8 ↔ collection #3" + }, + { + "actor_name": "LVL_Z4_COLL_01_BlueMarble", + "asset_key": "CirclePlatform", + "asset_type": "static_mesh", + "category": "COLL", + "zone_id": "Z4", + "location": [ + 3900.0, + 1700.0, + 10.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.03, + 0.03, + 0.03 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z4_空地/Collectibles", + "note": "收集品占位标记", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "普通", + "source_ref": "collection #1" + }, + { + "actor_name": "LVL_Z4_COLL_03_SmallStone", + "asset_key": "CirclePlatform", + "asset_type": "static_mesh", + "category": "COLL", + "zone_id": "Z4", + "location": [ + 4550.0, + 1550.0, + 10.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.03, + 0.03, + 0.03 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z4_空地/Collectibles", + "note": "收集品占位标记", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "普通", + "source_ref": "collection #3" + }, + { + "actor_name": "LVL_Z4_COLL_04_LuZhishenCard", + "asset_key": "CirclePlatform", + "asset_type": "static_mesh", + "category": "COLL", + "zone_id": "Z4", + "location": [ + 3720.0, + 1610.0, + 10.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.03, + 0.03, + 0.03 + ], + "material": "MI_DevYellow", + "folder": "LVL_SuburbanV01/Z4_空地/Collectibles", + "note": "收集品占位标记", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "稀有", + "source_ref": "collection #4" + }, + { + "actor_name": "LVL_Z5_STR_WestWall_01", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z5", + "location": [ + 2300.0, + 1500.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z5_巷子/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z5_STR_WestWall_02", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z5", + "location": [ + 2300.0, + 1900.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z5_巷子/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z5_STR_WestWall_03", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z5", + "location": [ + 2300.0, + 2300.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z5_巷子/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z5_STR_WestWall_04", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z5", + "location": [ + 2300.0, + 2700.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z5_巷子/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z5_STR_WestWall_05", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z5", + "location": [ + 2300.0, + 3100.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z5_巷子/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z5_STR_EastWall_01", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z5", + "location": [ + 2580.0, + 1500.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z5_巷子/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z5_STR_EastWall_02", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z5", + "location": [ + 2580.0, + 1900.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z5_巷子/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z5_STR_EastWall_03", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z5", + "location": [ + 2580.0, + 2300.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z5_巷子/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z5_STR_EastWall_04", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z5", + "location": [ + 2580.0, + 2700.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z5_巷子/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z5_STR_EastWall_05", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z5", + "location": [ + 2580.0, + 3100.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z5_巷子/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z5_PROP_WasteBox", + "asset_key": "WoodenBox_Small", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z5", + "location": [ + 2380.0, + 2900.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "", + "folder": "LVL_SuburbanV01/Z5_巷子/Props", + "note": "巷子深处靠西墙", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z5_PROP_SpiderWeb", + "asset_key": "Cube", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z5", + "location": [ + 2305.0, + 2100.0, + 250.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.3, + 0.3, + 0.01 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z5_巷子/Props", + "note": "西墙高处薄片", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z5_PROP_OldWindow", + "asset_key": "FakeWindowsFrame", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z5", + "location": [ + 2310.0, + 2100.0, + 150.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z5_巷子/Props", + "note": "西墙中段", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z5_PROP_FlowerPot", + "asset_key": "Cylinder", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z5", + "location": [ + 2340.0, + 2100.0, + 150.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.2, + 0.2, + 0.25 + ], + "material": "MI_DevGreen", + "folder": "LVL_SuburbanV01/Z5_巷子/Props", + "note": "窗台花盆", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z5_PROP_Moss", + "asset_key": "Cube", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z5", + "location": [ + 2400.0, + 2700.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.6, + 0.4, + 0.01 + ], + "material": "MI_DevFoliage", + "folder": "LVL_SuburbanV01/Z5_巷子/Props", + "note": "地面青苔", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z5_INTR_10_WasteBox", + "asset_key": "Cube", + "asset_type": "static_mesh", + "category": "INTR", + "zone_id": "Z5", + "location": [ + 2380.0, + 2900.0, + 25.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.3, + 0.3, + 0.3 + ], + "material": "MI_DevYellow", + "folder": "LVL_SuburbanV01/Z5_巷子/Interactables", + "note": "交互物占位标记", + "trigger_radius": 150.0, + "interact_type": "", + "rarity": "", + "source_ref": "interaction #10" + }, + { + "actor_name": "LVL_Z5_COLL_02_RedMarble", + "asset_key": "CirclePlatform", + "asset_type": "static_mesh", + "category": "COLL", + "zone_id": "Z5", + "location": [ + 2500.0, + 3000.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.03, + 0.03, + 0.03 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z5_巷子/Collectibles", + "note": "收集品占位标记", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "普通", + "source_ref": "collection #2" + }, + { + "actor_name": "LVL_Z6_STR_EastBound_01", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z6", + "location": [ + 3080.0, + 3600.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z6_水塘边/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z6_STR_EastBound_02", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z6", + "location": [ + 3080.0, + 4200.0, + 0.0 + ], + "rotation": [ + 0.0, + 90.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z6_水塘边/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z6_STR_NorthBound_01", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z6", + "location": [ + 1900.0, + 4680.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z6_水塘边/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z6_STR_NorthBound_02", + "asset_key": "BarrierWall_600", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z6", + "location": [ + 2500.0, + 4680.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z6_水塘边/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z6_STR_NorthBound_03", + "asset_key": "BarrierWall_200", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z6", + "location": [ + 2800.0, + 4680.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevBlue", + "folder": "LVL_SuburbanV01/Z6_水塘边/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z6_PROP_Reeds_S1~5", + "asset_key": "Cylinder", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z6", + "location": [ + 1800.0, + 3600.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.08, + 0.08, + 2.0 + ], + "material": "MI_DevFoliage", + "folder": "LVL_SuburbanV01/Z6_水塘边/Props", + "note": "南岸左 5 根", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z6_PROP_Reeds_S2_1~5", + "asset_key": "Cylinder", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z6", + "location": [ + 2700.0, + 3600.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.08, + 0.08, + 2.0 + ], + "material": "MI_DevFoliage", + "folder": "LVL_SuburbanV01/Z6_水塘边/Props", + "note": "南岸右 5 根", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z6_PROP_Reeds_E_1~3", + "asset_key": "Cylinder", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z6", + "location": [ + 2900.0, + 4100.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.08, + 0.08, + 1.6 + ], + "material": "MI_DevFoliage", + "folder": "LVL_SuburbanV01/Z6_水塘边/Props", + "note": "东岸 3 根", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z6_PROP_LilyPad_1~4", + "asset_key": "CirclePlatform", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z6", + "location": [ + 2200.0, + 3900.0, + -18.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.06, + 0.06, + 0.01 + ], + "material": "MI_DevGreen", + "folder": "LVL_SuburbanV01/Z6_水塘边/Props", + "note": "水面荷叶", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z6_PROP_Frog", + "asset_key": "Cube", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z6", + "location": [ + 2100.0, + 3680.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.05, + 0.05, + 0.04 + ], + "material": "MI_DevGreen", + "folder": "LVL_SuburbanV01/Z6_水塘边/Props", + "note": "南岸小青蛙", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z6_COLL_05_CandyWrapper", + "asset_key": "CirclePlatform", + "asset_type": "static_mesh", + "category": "COLL", + "zone_id": "Z6", + "location": [ + 2000.0, + 3500.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.03, + 0.03, + 0.03 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z6_水塘边/Collectibles", + "note": "收集品占位标记", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "普通", + "source_ref": "collection #5" + }, + { + "actor_name": "LVL_Z6_COLL_06_Eraser", + "asset_key": "CirclePlatform", + "asset_type": "static_mesh", + "category": "COLL", + "zone_id": "Z6", + "location": [ + 2500.0, + 3450.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.03, + 0.03, + 0.03 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z6_水塘边/Collectibles", + "note": "收集品占位标记", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "普通", + "source_ref": "collection #6" + }, + { + "actor_name": "LVL_Z7_STR_Building", + "asset_key": "Building_01", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 6400.0, + 800.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z7_STR_CollisionFront", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 6200.0, + 150.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z7_STR_CollisionFront2", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 6600.0, + 150.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z7_STR_CollisionFront3", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 7000.0, + 150.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z7_STR_CollisionSide", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 5750.0, + 400.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.0, + 90.0, + 0.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z7_STR_CollisionSide2", + "asset_key": "Wall_400x300", + "asset_type": "static_mesh", + "category": "STR", + "zone_id": "Z7", + "location": [ + 5750.0, + 800.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 0.0, + 90.0, + 0.0 + ], + "material": "MI_DevGray", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Structure", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z7_PROP_ClothesPole_01", + "asset_key": "Beam_300", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z7", + "location": [ + 6100.0, + 190.0, + 800.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Props", + "note": "阳台晾衣杆", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z7_PROP_ClothesPole_02", + "asset_key": "Beam_300", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z7", + "location": [ + 6500.0, + 190.0, + 1200.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Props", + "note": "不同楼层", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z7_PROP_ClothesPole_03", + "asset_key": "Beam_300", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z7", + "location": [ + 6900.0, + 190.0, + 1600.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevWhite", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Props", + "note": "不同楼层", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z7_PROP_TrashCan", + "asset_key": "TrashCans_01", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z7", + "location": [ + 6000.0, + 140.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGreen", + "folder": "LVL_SuburbanV01/Z7_老居民楼/Props", + "note": "楼下地面", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_LGT_StreetLight_01", + "asset_key": "RoadLamp_01", + "asset_type": "static_mesh", + "category": "LGT", + "zone_id": "Z3", + "location": [ + 1500.0, + 1050.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "", + "folder": "LVL_SuburbanV01/Z3_主街道/Lighting", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_LGT_StreetLight_02", + "asset_key": "RoadLamp_01", + "asset_type": "static_mesh", + "category": "LGT", + "zone_id": "Z3", + "location": [ + 3000.0, + 1050.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "", + "folder": "LVL_SuburbanV01/Z3_主街道/Lighting", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_LGT_StreetLight_03", + "asset_key": "RoadLamp_01", + "asset_type": "static_mesh", + "category": "LGT", + "zone_id": "Z3", + "location": [ + 4500.0, + 1050.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "", + "folder": "LVL_SuburbanV01/Z3_主街道/Lighting", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_PROP_TrashCan_02", + "asset_key": "TrashCans_01", + "asset_type": "static_mesh", + "category": "PROP", + "zone_id": "Z3", + "location": [ + 2000.0, + 850.0, + 0.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "MI_DevGreen", + "folder": "LVL_SuburbanV01/Z3_主街道/Props", + "note": "", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Global_DirectionalLight", + "asset_key": "", + "asset_type": "directional_light", + "category": "LGT", + "zone_id": "GLOBAL", + "location": [ + 0, + 0, + 500 + ], + "rotation": [ + -45, + 315, + 0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "", + "folder": "LVL_SuburbanV01/Global/Lighting", + "note": "色温~5500K暖白;从西南照射;强度中等", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Global_SkyLight", + "asset_key": "", + "asset_type": "sky_light", + "category": "LGT", + "zone_id": "GLOBAL", + "location": [ + 0, + 0, + 0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "", + "folder": "LVL_SuburbanV01/Global/Lighting", + "note": "强度低-中;环境补光", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_LGT_PointLight_01", + "asset_key": "", + "asset_type": "point_light", + "category": "LGT", + "zone_id": "Z3", + "location": [ + 1500.0, + 1050.0, + 400.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "", + "folder": "LVL_SuburbanV01/Global/Lighting", + "note": "暖黄色,低强度", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_LGT_PointLight_02", + "asset_key": "", + "asset_type": "point_light", + "category": "LGT", + "zone_id": "Z3", + "location": [ + 3000.0, + 1050.0, + 400.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "", + "folder": "LVL_SuburbanV01/Global/Lighting", + "note": "暖黄色,低强度", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_Z3_LGT_PointLight_03", + "asset_key": "", + "asset_type": "point_light", + "category": "LGT", + "zone_id": "Z3", + "location": [ + 4500.0, + 1050.0, + 400.0 + ], + "rotation": [ + 0.0, + 0.0, + 0.0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "", + "folder": "LVL_SuburbanV01/Global/Lighting", + "note": "暖黄色,低强度", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + }, + { + "actor_name": "LVL_PlayerStart", + "asset_key": "", + "asset_type": "player_start", + "category": "PLAY", + "zone_id": "GLOBAL", + "location": [ + 500, + 720, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1.0, + 1.0, + 1.0 + ], + "material": "", + "folder": "LVL_SuburbanV01/Global/PlayerStart", + "note": "Z1 院内院门内侧约60cm,面向+Y(北)", + "trigger_radius": 0.0, + "interact_type": "", + "rarity": "", + "source_ref": "" + } + ], + "summary": { + "total_actors": 265, + "by_category": { + "STR": 123, + "BND": 61, + "PROP": 53, + "INTR": 10, + "COLL": 9, + "LGT": 8, + "PLAY": 1 + }, + "by_zone": { + "Z1": 40, + "Z2": 26, + "Z3": 42, + "Z4": 20, + "Z5": 19, + "Z6": 16, + "Z7": 38, + "GLOBAL": 64 + }, + "unique_assets": 37, + "asset_list": [ + "Barrel", + "BarrierWall_200", + "BarrierWall_600", + "Beam_300", + "BedSingle", + "Bucket_01", + "Building_01", + "Car01", + "CirclePlatform", + "Container_Normal", + "Cube", + "Cylinder", + "DisplayPanels_400x200", + "FakeWindowsFrame", + "Fence_Small_400", + "Floor_1000x1000", + "Floor_200x300", + "Floor_300x400", + "GarageDoorOpen_01", + "Monitor_01", + "RoadLamp_01", + "RotativeDoor_01", + "SimpleTable_01", + "SimpleTable_02", + "TrashCans_01", + "Tree_01", + "WallDoorGarage_400x300", + "WallDoor_200x300", + "WallWindowSmall_200x300", + "WallWindow_400x300", + "Wall_100x300", + "Wall_200x300", + "Wall_400x100", + "Wall_400x300", + "WoodenBox_Normal", + "WoodenBox_Small", + "WoodenPallet_01" + ] + } +} \ No newline at end of file diff --git a/tools/level-builder/output/validation_result.json b/tools/level-builder/output/validation_result.json new file mode 100644 index 0000000..dd85a60 --- /dev/null +++ b/tools/level-builder/output/validation_result.json @@ -0,0 +1,9 @@ +{ + "is_valid": true, + "total": 265, + "valid": 265, + "errors": [], + "warnings": [], + "missing_assets": [], + "missing_materials": [] +} \ No newline at end of file diff --git a/tools/level-builder/output/搭建报告-auto.md b/tools/level-builder/output/搭建报告-auto.md new file mode 100644 index 0000000..805bb89 --- /dev/null +++ b/tools/level-builder/output/搭建报告-auto.md @@ -0,0 +1,455 @@ +# 白模搭建报告 — 自动生成 + +> 生成时间: 2026-06-07 23:03 +> 数据来源: 关卡-v01-搭建指南.md +> 场景尺寸: 8000cm × 6000cm + +## 一、搭建概要 + +- **总 Actor 数**: 265 +- 结构体 (STR): 123 +- 布景 (PROP): 53 +- 交互物 (INTR): 10 +- 收集品 (COLL): 9 +- 边界 (BND): 61 +- 光源 (LGT): 8 +- PlayerStart (PLAY): 1 + +## 二、逐区域对照 + +### Z1 家 + +共 40 个 Actor + +| # | Actor 名称 | 资产 | 位置 | 缩放 | 材质 | 状态 | +|---|-----------|------|------|------|------|------| +| 1 | LVL_Z1_STR_Floor | Floor_1000x1000 | (500,400,0) | (1.00,0.80,1.00) | MI_DevGray | ✅ | +| 2 | LVL_Z1_STR_SouthWall_01 | Wall_400x300 | (200,0,0) | — | MI_DevRed | ✅ | +| 3 | LVL_Z1_STR_SouthWall_02 | Wall_400x300 | (600,0,0) | — | MI_DevRed | ✅ | +| 4 | LVL_Z1_STR_WestWall_01 | Wall_400x300 | (0,200,0) | — | MI_DevRed | ✅ | +| 5 | LVL_Z1_STR_WestWall_02 | Wall_400x300 | (0,600,0) | — | MI_DevRed | ✅ | +| 6 | LVL_Z1_STR_EastWall_01 | Wall_400x300 | (980,200,0) | — | MI_DevRed | ✅ | +| 7 | LVL_Z1_STR_EastWall_02 | Wall_400x300 | (980,600,0) | — | MI_DevRed | ✅ | +| 8 | LVL_Z1_STR_NorthWall_West | Wall_400x300 | (200,780,0) | — | MI_DevRed | ✅ | +| 9 | LVL_Z1_STR_NorthWall_Gate | WallDoor_200x300 | (500,780,0) | — | MI_DevRed | ✅ | +| 10 | LVL_Z1_STR_NorthWall_East | Wall_400x300 | (800,780,0) | — | MI_DevRed | ✅ | +| 11 | LVL_Z1_STR_GateDoor | RotativeDoor_01 | (500,780,0) | — | MI_DevGreen | ✅ | +| 12 | LVL_Z1_STR_HouseSouthWall | WallWindow_400x300 | (400,30,0) | — | MI_DevWhite | ✅ | +| 13 | LVL_Z1_STR_HouseSouthWin | WallWindowSmall_200x300 | (600,30,0) | — | MI_DevWhite | ✅ | +| 14 | LVL_Z1_STR_HouseWestWall | Wall_400x300 | (200,220,0) | — | MI_DevWhite | ✅ | +| 15 | LVL_Z1_STR_HouseWestTop | Wall_400x100 | (200,220,300) | — | MI_DevWhite | ✅ | +| 16 | LVL_Z1_STR_HouseEastWall | Wall_400x300 | (780,220,0) | — | MI_DevWhite | ✅ | +| 17 | LVL_Z1_STR_HouseEastTop | Wall_400x100 | (780,220,300) | — | MI_DevWhite | ✅ | +| 18 | LVL_Z1_STR_HouseNorthWall | WallDoor_200x300 | (400,410,0) | — | MI_DevWhite | ✅ | +| 19 | LVL_Z1_STR_HouseNorthFill | Wall_400x300 | (600,410,0) | — | MI_DevWhite | ✅ | +| 20 | LVL_Z1_STR_HouseRoof_01 | Floor_300x400 | (350,230,280) | — | MI_DevBrown | ✅ | +| 21 | LVL_Z1_STR_HouseRoof_02 | Floor_300x400 | (650,230,280) | — | MI_DevBrown | ✅ | +| 22 | LVL_Z1_STR_CourtyardFloor | Floor_1000x1000 | (500,400,0) | (1.00,0.80,1.00) | MI_DevGray | ✅ | +| 23 | LVL_Z1_PROP_OldBicycle | Car01 | (100,650,0) | (0.20,0.20,0.20) | — | ✅ | +| 24 | LVL_Z1_PROP_ClothesPole_Beam | Beam_300 | (500,600,180) | — | MI_DevWhite | ✅ | +| 25 | LVL_Z1_PROP_ClothesPole_Pole1 | Cylinder | (380,600,0) | (0.05,0.05,3.60) | MI_DevGray | ✅ | +| 26 | LVL_Z1_PROP_ClothesPole_Pole2 | Cylinder | (620,600,0) | (0.05,0.05,3.60) | MI_DevGray | ✅ | +| 27 | LVL_Z1_PROP_JunkPile_Box1 | WoodenBox_Small | (850,100,0) | — | — | ✅ | +| 28 | LVL_Z1_PROP_JunkPile_Box2 | WoodenBox_Small | (870,120,35) | — | — | ✅ | +| 29 | LVL_Z1_PROP_JunkPile_Bucket | Bucket_01 | (890,80,0) | — | — | ✅ | +| 30 | LVL_Z1_PROP_DoorMat | Cube | (480,740,0) | (0.60,0.40,0.02) | MI_DevGray | ✅ | +| 31 | LVL_Z1_PROP_Fridge | Barrel | (720,80,0) | (0.30,0.30,1.60) | MI_DevWhite | ✅ | +| 32 | LVL_Z1_PROP_TV | Monitor_01 | (320,80,45) | — | MI_DevGray | ✅ | +| 33 | LVL_Z1_PROP_Desk | SimpleTable_01 | (300,70,0) | — | — | ✅ | +| 34 | LVL_Z1_PROP_Bed | BedSingle | (350,250,0) | — | — | ✅ | +| 35 | LVL_Z1_PROP_Calendar | Cube | (500,40,180) | (0.30,0.02,0.40) | MI_DevRed | ✅ | +| 36 | LVL_Z1_PROP_TVStand | SimpleTable_02 | (320,55,0) | (0.85,0.75,0.67) | — | ✅ | +| 37 | LVL_Z1_INTR_01_Fridge | Cube | (720,80,80) | (0.30,0.30,0.30) | MI_DevYellow | ✅ | +| 38 | LVL_Z1_INTR_02_Gate | Cube | (500,780,0) | (0.30,0.30,0.30) | MI_DevYellow | ✅ | +| 39 | LVL_Z1_INTR_06_TV | Cube | (320,80,70) | (0.30,0.30,0.30) | MI_DevYellow | ✅ | +| 40 | LVL_Z1_COLL_10_CatEyeMarble | CirclePlatform | (870,140,0) | (0.03,0.03,0.03) | MI_DevYellow | ✅ | + +### Z2 小卖部 + +共 26 个 Actor + +| # | Actor 名称 | 资产 | 位置 | 缩放 | 材质 | 状态 | +|---|-----------|------|------|------|------|------| +| 1 | LVL_Z2_STR_Floor | Floor_1000x1000 | (1300,500,0) | (0.60,0.60,1.00) | MI_DevGray | ✅ | +| 2 | LVL_Z2_STR_SouthWall | Wall_400x300 | (1200,200,0) | — | MI_DevOrange | ✅ | +| 3 | LVL_Z2_STR_SouthWall2 | Wall_200x300 | (1500,200,0) | — | MI_DevOrange | ✅ | +| 4 | LVL_Z2_STR_WestWall | Wall_400x300 | (1000,400,0) | — | MI_DevOrange | ✅ | +| 5 | LVL_Z2_STR_WestWallTop | Wall_400x100 | (1000,400,300) | — | MI_DevOrange | ✅ | +| 6 | LVL_Z2_STR_EastWall | Wall_400x300 | (1580,400,0) | — | MI_DevOrange | ✅ | +| 7 | LVL_Z2_STR_EastWallTop | Wall_400x100 | (1580,400,300) | — | MI_DevOrange | ✅ | +| 8 | LVL_Z2_STR_NorthWall_West | Wall_200x300 | (1100,580,0) | — | MI_DevOrange | ✅ | +| 9 | LVL_Z2_STR_NorthWall_Garage | WallDoorGarage_400x300 | (1300,580,0) | — | MI_DevOrange | ✅ | +| 10 | LVL_Z2_STR_NorthWall_East | Wall_200x300 | (1500,580,0) | — | MI_DevOrange | ✅ | +| 11 | LVL_Z2_STR_GarageDoor | GarageDoorOpen_01 | (1300,580,0) | — | MI_DevGray | ✅ | +| 12 | LVL_Z2_STR_Roof_01 | Floor_300x400 | (1250,400,280) | — | MI_DevBrown | ✅ | +| 13 | LVL_Z2_STR_Roof_02 | Floor_300x400 | (1350,400,280) | — | MI_DevBrown | ✅ | +| 14 | LVL_Z2_STR_Awning_01 | Floor_200x300 | (1100,700,260) | — | MI_DevWhite | ✅ | +| 15 | LVL_Z2_STR_Awning_02 | Floor_200x300 | (1400,700,260) | — | MI_DevWhite | ✅ | +| 16 | LVL_Z2_PROP_Counter | Cube | (1200,500,0) | (2.00,0.60,0.90) | MI_DevGlassWhite | ✅ | +| 17 | LVL_Z2_PROP_ShelfEast_01 | Fence_Small_400 | (1520,300,0) | (1.00,1.00,1.80) | MI_DevGray | ✅ | +| 18 | LVL_Z2_PROP_ShelfEast_02 | Fence_Small_400 | (1520,300,180) | (1.00,1.00,1.80) | MI_DevGray | ✅ | +| 19 | LVL_Z2_PROP_ShelfSouth | Fence_Small_400 | (1100,230,0) | (1.00,1.00,1.80) | MI_DevGray | ✅ | +| 20 | LVL_Z2_PROP_Freezer | Container_Normal | (1050,400,0) | (0.25,0.15,0.40) | MI_DevWhite | ✅ | +| 21 | LVL_Z2_PROP_SmallTV | Monitor_01 | (1350,540,90) | (0.60,0.60,0.60) | MI_DevGray | ✅ | +| 22 | LVL_Z2_PROP_Signboard | Cube | (1150,610,280) | (3.00,0.05,0.40) | MI_DevBlue | ✅ | +| 23 | LVL_Z2_PROP_CardRack | Cube | (1400,550,0) | (0.40,0.20,0.30) | MI_DevGray | ✅ | +| 24 | LVL_Z2_INTR_05_ShopOwner | Cube | (1300,480,0) | (0.30,0.30,0.30) | MI_DevYellow | ✅ | +| 25 | LVL_Z2_INTR_07_SnackShelf | Cube | (1520,350,90) | (0.30,0.30,0.30) | MI_DevYellow | ✅ | +| 26 | LVL_Z2_COLL_09_BouncyBall | CirclePlatform | (1300,700,0) | (0.03,0.03,0.03) | MI_DevWhite | ✅ | + +### Z3 主街道 + +共 42 个 Actor + +| # | Actor 名称 | 资产 | 位置 | 缩放 | 材质 | 状态 | +|---|-----------|------|------|------|------|------| +| 1 | LVL_Z3_STR_Floor_01 | Floor_1000x1000 | (500,1050,0) | (1.00,0.50,1.00) | MI_DevGray | ✅ | +| 2 | LVL_Z3_STR_Floor_02 | Floor_1000x1000 | (1500,1050,0) | (1.00,0.50,1.00) | MI_DevGray | ✅ | +| 3 | LVL_Z3_STR_Floor_03 | Floor_1000x1000 | (2500,1050,0) | (1.00,0.50,1.00) | MI_DevGray | ✅ | +| 4 | LVL_Z3_STR_Floor_04 | Floor_1000x1000 | (3500,1050,0) | (1.00,0.50,1.00) | MI_DevGray | ✅ | +| 5 | LVL_Z3_STR_Floor_05 | Floor_1000x1000 | (4500,1050,0) | (1.00,0.50,1.00) | MI_DevGray | ✅ | +| 6 | LVL_Z3_STR_SouthWall_C1 | Wall_400x300 | (1800,800,0) | — | MI_DevGray | ✅ | +| 7 | LVL_Z3_STR_SouthWall_C2 | Wall_400x300 | (2200,800,0) | — | MI_DevGray | ✅ | +| 8 | LVL_Z3_STR_SouthWall_C3 | Wall_400x300 | (2600,800,0) | — | MI_DevGray | ✅ | +| 9 | LVL_Z3_STR_SouthWall_C4 | Wall_400x300 | (3000,800,0) | — | MI_DevGray | ✅ | +| 10 | LVL_Z3_STR_SouthWall_C5 | Wall_400x300 | (3400,800,0) | — | MI_DevGray | ✅ | +| 11 | LVL_Z3_STR_SouthWall_C6 | Wall_400x300 | (3800,800,0) | — | MI_DevGray | ✅ | +| 12 | LVL_Z3_STR_SouthWall_D1 | Wall_400x300 | (4200,800,0) | — | MI_DevGray | ✅ | +| 13 | LVL_Z3_STR_SouthWall_D2 | Wall_400x300 | (4600,800,0) | — | MI_DevGray | ✅ | +| 14 | LVL_Z3_STR_NorthWall_A1 | Wall_400x300 | (200,1300,0) | — | MI_DevGray | ✅ | +| 15 | LVL_Z3_STR_NorthWall_A2 | Wall_400x300 | (600,1300,0) | — | MI_DevGray | ✅ | +| 16 | LVL_Z3_STR_NorthWall_A3 | Wall_400x300 | (1000,1300,0) | — | MI_DevGray | ✅ | +| 17 | LVL_Z3_STR_NorthWall_A4 | Wall_400x300 | (1400,1300,0) | — | MI_DevGray | ✅ | +| 18 | LVL_Z3_STR_NorthWall_A5 | Wall_400x300 | (1800,1300,0) | — | MI_DevGray | ✅ | +| 19 | LVL_Z3_STR_NorthWall_A6 | Wall_200x300 | (2100,1300,0) | — | MI_DevGray | ✅ | +| 20 | LVL_Z3_STR_NorthWall_C1 | Wall_400x300 | (2800,1300,0) | — | MI_DevGray | ✅ | +| 21 | LVL_Z3_STR_NorthWall_C2 | Wall_400x300 | (3200,1300,0) | — | MI_DevGray | ✅ | +| 22 | LVL_Z3_STR_NorthWall_C3 | Wall_100x300 | (3450,1300,0) | — | MI_DevGray | ✅ | +| 23 | LVL_Z3_PROP_PhoneBooth | Cube | (1800,380,0) | (0.80,0.80,2.20) | MI_DevGray | ✅ | +| 24 | LVL_Z3_PROP_Bicycle | Car01 | (2800,880,0) | (0.20,0.20,0.20) | — | ✅ | +| 25 | LVL_Z3_PROP_ClothesPole | Beam_300 | (1200,1250,180) | — | MI_DevWhite | ✅ | +| 26 | LVL_Z3_PROP_ClothesPolePole | Cylinder | (1200,1250,0) | (0.05,0.05,3.60) | MI_DevGray | ✅ | +| 27 | LVL_Z3_PROP_SewerCover | CirclePlatform | (800,1050,0) | (0.12,0.12,0.02) | MI_DevGray | ✅ | +| 28 | LVL_Z3_PROP_Graffiti | Cube | (3200,1270,100) | (1.20,0.05,0.80) | MI_DevYellow | ✅ | +| 29 | LVL_Z3 PROP_AdWall | DisplayPanels_400x200 | (3800,1280,0) | — | MI_DevGray | ✅ | +| 30 | LVL_Z3_PROP_TrashCan | TrashCans_01 | (4200,850,0) | — | MI_DevGreen | ✅ | +| 31 | LVL_Z3_PROP_PoleWest | Cylinder | (1000,1050,0) | (0.04,0.04,12.00) | MI_DevGray | ✅ | +| 32 | LVL_Z3_PROP_PoleEast | Cylinder | (3500,1050,0) | (0.04,0.04,12.00) | MI_DevGray | ✅ | +| 33 | LVL_Z3_INTR_04_PhoneBooth | Cube | (1800,380,110) | (0.30,0.30,0.30) | MI_DevYellow | ✅ | +| 34 | LVL_Z3_INTR_09_Graffiti | Cube | (3200,1270,140) | (0.30,0.30,0.30) | MI_DevYellow | ✅ | +| 35 | LVL_Z3_COLL_08_IceFlowerMarble | CirclePlatform | (820,1060,0) | (0.03,0.03,0.03) | MI_DevWhite | ✅ | +| 36 | LVL_Z3_LGT_StreetLight_01 | RoadLamp_01 | (1500,1050,0) | — | — | ✅ | +| 37 | LVL_Z3_LGT_StreetLight_02 | RoadLamp_01 | (3000,1050,0) | — | — | ✅ | +| 38 | LVL_Z3_LGT_StreetLight_03 | RoadLamp_01 | (4500,1050,0) | — | — | ✅ | +| 39 | LVL_Z3_PROP_TrashCan_02 | TrashCans_01 | (2000,850,0) | — | MI_DevGreen | ✅ | +| 40 | LVL_Z3_LGT_PointLight_01 | | (1500,1050,400) | — | — | ✅ | +| 41 | LVL_Z3_LGT_PointLight_02 | | (3000,1050,400) | — | — | ✅ | +| 42 | LVL_Z3_LGT_PointLight_03 | | (4500,1050,400) | — | — | ✅ | + +### Z4 空地 + +共 20 个 Actor + +| # | Actor 名称 | 资产 | 位置 | 缩放 | 材质 | 状态 | +|---|-----------|------|------|------|------|------| +| 1 | LVL_Z4_STR_Floor_01 | Floor_1000x1000 | (4000,1800,10) | (1.50,1.20,1.00) | MI_DevBrown | ✅ | +| 2 | LVL_Z4_STR_EastBound_01 | BarrierWall_600 | (4980,1600,0) | — | MI_DevBlue | ✅ | +| 3 | LVL_Z4_STR_EastBound_02 | BarrierWall_600 | (4980,2200,0) | — | MI_DevBlue | ✅ | +| 4 | LVL_Z4_STR_NorthBound_01 | BarrierWall_600 | (3800,2480,0) | — | MI_DevBlue | ✅ | +| 5 | LVL_Z4_STR_NorthBound_02 | BarrierWall_600 | (4400,2480,0) | — | MI_DevBlue | ✅ | +| 6 | LVL_Z4_STR_NorthBound_03 | BarrierWall_200 | (4700,2480,0) | — | MI_DevBlue | ✅ | +| 7 | LVL_Z4_STR_WestLowWall_01 | BarrierWall_200 | (3500,1500,0) | — | MI_DevGray | ✅ | +| 8 | LVL_Z4_STR_WestLowWall_02 | BarrierWall_200 | (3500,1900,0) | — | MI_DevGray | ✅ | +| 9 | LVL_Z4_STR_WestLowWall_03 | BarrierWall_200 | (3500,2300,0) | — | MI_DevGray | ✅ | +| 10 | LVL_Z4_PROP_BigTree | Tree_01 | (4250,1900,10) | (1.20,1.20,1.20) | MI_DevFoliage | ✅ | +| 11 | LVL_Z4_PROP_Bricks_01~05 | WoodenBox_Small | (0,0,0) | — | — | ✅ | +| 12 | LVL_Z4_PROP_Puddle | Cube | (4600,1500,5) | (1.20,0.80,0.01) | MI_DevGlassBlue | ✅ | +| 13 | LVL_Z4_PROP_MarbleCircle | CirclePlatform | (4100,1800,12) | (0.16,0.16,0.01) | MI_DevGray | ✅ | +| 14 | LVL_Z4_PROP_Debris_01 | WoodenPallet_01 | (4800,2300,10) | — | — | ✅ | +| 15 | LVL_Z4_PROP_Debris_02 | WoodenBox_Normal | (4850,2250,10) | — | — | ✅ | +| 16 | LVL_Z4_INTR_03_BlueMarble | Cube | (3900,1700,10) | (0.30,0.30,0.30) | MI_DevYellow | ✅ | +| 17 | LVL_Z4_INTR_08_SmallStone | Cube | (4550,1550,10) | (0.30,0.30,0.30) | MI_DevYellow | ✅ | +| 18 | LVL_Z4_COLL_01_BlueMarble | CirclePlatform | (3900,1700,10) | (0.03,0.03,0.03) | MI_DevWhite | ✅ | +| 19 | LVL_Z4_COLL_03_SmallStone | CirclePlatform | (4550,1550,10) | (0.03,0.03,0.03) | MI_DevWhite | ✅ | +| 20 | LVL_Z4_COLL_04_LuZhishenCard | CirclePlatform | (3720,1610,10) | (0.03,0.03,0.03) | MI_DevYellow | ✅ | + +### Z5 巷子 + +共 19 个 Actor + +| # | Actor 名称 | 资产 | 位置 | 缩放 | 材质 | 状态 | +|---|-----------|------|------|------|------|------| +| 1 | LVL_Z5_STR_Floor_01 | Floor_1000x1000 | (2450,1800,0) | (0.30,1.00,1.00) | MI_DevGray | ✅ | +| 2 | LVL_Z5_STR_Floor_02 | Floor_1000x1000 | (2450,2800,0) | (0.30,1.00,1.00) | MI_DevGray | ✅ | +| 3 | LVL_Z5_STR_WestWall_01 | Wall_400x300 | (2300,1500,0) | — | MI_DevWhite | ✅ | +| 4 | LVL_Z5_STR_WestWall_02 | Wall_400x300 | (2300,1900,0) | — | MI_DevWhite | ✅ | +| 5 | LVL_Z5_STR_WestWall_03 | Wall_400x300 | (2300,2300,0) | — | MI_DevWhite | ✅ | +| 6 | LVL_Z5_STR_WestWall_04 | Wall_400x300 | (2300,2700,0) | — | MI_DevWhite | ✅ | +| 7 | LVL_Z5_STR_WestWall_05 | Wall_400x300 | (2300,3100,0) | — | MI_DevWhite | ✅ | +| 8 | LVL_Z5_STR_EastWall_01 | Wall_400x300 | (2580,1500,0) | — | MI_DevWhite | ✅ | +| 9 | LVL_Z5_STR_EastWall_02 | Wall_400x300 | (2580,1900,0) | — | MI_DevWhite | ✅ | +| 10 | LVL_Z5_STR_EastWall_03 | Wall_400x300 | (2580,2300,0) | — | MI_DevWhite | ✅ | +| 11 | LVL_Z5_STR_EastWall_04 | Wall_400x300 | (2580,2700,0) | — | MI_DevWhite | ✅ | +| 12 | LVL_Z5_STR_EastWall_05 | Wall_400x300 | (2580,3100,0) | — | MI_DevWhite | ✅ | +| 13 | LVL_Z5_PROP_WasteBox | WoodenBox_Small | (2380,2900,0) | — | — | ✅ | +| 14 | LVL_Z5_PROP_SpiderWeb | Cube | (2305,2100,250) | (0.30,0.30,0.01) | MI_DevWhite | ✅ | +| 15 | LVL_Z5_PROP_OldWindow | FakeWindowsFrame | (2310,2100,150) | — | MI_DevGray | ✅ | +| 16 | LVL_Z5_PROP_FlowerPot | Cylinder | (2340,2100,150) | (0.20,0.20,0.25) | MI_DevGreen | ✅ | +| 17 | LVL_Z5_PROP_Moss | Cube | (2400,2700,0) | (0.60,0.40,0.01) | MI_DevFoliage | ✅ | +| 18 | LVL_Z5_INTR_10_WasteBox | Cube | (2380,2900,25) | (0.30,0.30,0.30) | MI_DevYellow | ✅ | +| 19 | LVL_Z5_COLL_02_RedMarble | CirclePlatform | (2500,3000,0) | (0.03,0.03,0.03) | MI_DevWhite | ✅ | + +### Z6 水塘边 + +共 16 个 Actor + +| # | Actor 名称 | 资产 | 位置 | 缩放 | 材质 | 状态 | +|---|-----------|------|------|------|------|------| +| 1 | LVL_Z6_STR_GroundSouth | Floor_1000x1000 | (2350,3475,0) | (1.50,0.35,1.00) | MI_DevBrown | ✅ | +| 2 | LVL_Z6_STR_GroundEast | Floor_1000x1000 | (3075,4000,0) | (0.15,0.80,1.00) | MI_DevBrown | ✅ | +| 3 | LVL_Z6_STR_GroundWest | Floor_1000x1000 | (1675,4000,0) | (0.15,0.80,1.00) | MI_DevBrown | ✅ | +| 4 | LVL_Z6_STR_Water | Floor_1000x1000 | (2350,4000,-20) | (1.20,0.80,0.50) | MI_DevSkyBlue | ✅ | +| 5 | LVL_Z6_STR_EastBound_01 | BarrierWall_600 | (3080,3600,0) | — | MI_DevBlue | ✅ | +| 6 | LVL_Z6_STR_EastBound_02 | BarrierWall_600 | (3080,4200,0) | — | MI_DevBlue | ✅ | +| 7 | LVL_Z6_STR_NorthBound_01 | BarrierWall_600 | (1900,4680,0) | — | MI_DevBlue | ✅ | +| 8 | LVL_Z6_STR_NorthBound_02 | BarrierWall_600 | (2500,4680,0) | — | MI_DevBlue | ✅ | +| 9 | LVL_Z6_STR_NorthBound_03 | BarrierWall_200 | (2800,4680,0) | — | MI_DevBlue | ✅ | +| 10 | LVL_Z6_PROP_Reeds_S1~5 | Cylinder | (1800,3600,0) | (0.08,0.08,2.00) | MI_DevFoliage | ✅ | +| 11 | LVL_Z6_PROP_Reeds_S2_1~5 | Cylinder | (2700,3600,0) | (0.08,0.08,2.00) | MI_DevFoliage | ✅ | +| 12 | LVL_Z6_PROP_Reeds_E_1~3 | Cylinder | (2900,4100,0) | (0.08,0.08,1.60) | MI_DevFoliage | ✅ | +| 13 | LVL_Z6_PROP_LilyPad_1~4 | CirclePlatform | (2200,3900,-18) | (0.06,0.06,0.01) | MI_DevGreen | ✅ | +| 14 | LVL_Z6_PROP_Frog | Cube | (2100,3680,0) | (0.05,0.05,0.04) | MI_DevGreen | ✅ | +| 15 | LVL_Z6_COLL_05_CandyWrapper | CirclePlatform | (2000,3500,0) | (0.03,0.03,0.03) | MI_DevWhite | ✅ | +| 16 | LVL_Z6_COLL_06_Eraser | CirclePlatform | (2500,3450,0) | (0.03,0.03,0.03) | MI_DevWhite | ✅ | + +### Z7 老居民楼 + +共 38 个 Actor + +| # | Actor 名称 | 资产 | 位置 | 缩放 | 材质 | 状态 | +|---|-----------|------|------|------|------|------| +| 1 | LVL_BND_West_01 | Wall_400x300 | (0,200,0) | — | MI_DevRed | ✅ | +| 2 | LVL_BND_West_02 | Wall_400x300 | (0,600,0) | — | MI_DevRed | ✅ | +| 3 | LVL_BND_West_03 | Wall_400x300 | (0,1000,0) | — | MI_DevRed | ✅ | +| 4 | LVL_BND_West_04 | Wall_400x300 | (0,1400,0) | — | MI_DevRed | ✅ | +| 5 | LVL_BND_West_05 | Wall_400x300 | (0,1800,0) | — | MI_DevRed | ✅ | +| 6 | LVL_BND_West_06 | Wall_400x300 | (0,2200,0) | — | MI_DevRed | ✅ | +| 7 | LVL_BND_West_07 | Wall_400x300 | (0,2600,0) | — | MI_DevRed | ✅ | +| 8 | LVL_BND_West_08 | Wall_400x300 | (0,3000,0) | — | MI_DevRed | ✅ | +| 9 | LVL_BND_West_09 | Wall_400x300 | (0,3400,0) | — | MI_DevRed | ✅ | +| 10 | LVL_BND_West_10 | Wall_400x300 | (0,3800,0) | — | MI_DevRed | ✅ | +| 11 | LVL_BND_West_11 | Wall_400x300 | (0,4200,0) | — | MI_DevRed | ✅ | +| 12 | LVL_BND_West_12 | Wall_400x300 | (0,4600,0) | — | MI_DevRed | ✅ | +| 13 | LVL_BND_West_13 | Wall_400x300 | (0,5000,0) | — | MI_DevRed | ✅ | +| 14 | LVL_BND_West_14 | Wall_400x300 | (0,5400,0) | — | MI_DevRed | ✅ | +| 15 | LVL_BND_West_15 | Wall_400x300 | (0,5800,0) | — | MI_DevRed | ✅ | +| 16 | LVL_BND_East_01~15 | BarrierWall_600 | (0,0,0) | — | MI_DevBlue | ✅ | +| 17 | LVL_BND_North_01~20 | Wall_400x300 | (0,0,0) | — | MI_DevBlue | ✅ | +| 18 | LVL_BND_South_01 | BarrierWall_600 | (1900,0,0) | — | MI_DevBlue | ✅ | +| 19 | LVL_BND_South_02 | BarrierWall_600 | (2500,0,0) | — | MI_DevBlue | ✅ | +| 20 | LVL_BND_South_03 | BarrierWall_600 | (3100,0,0) | — | MI_DevBlue | ✅ | +| 21 | LVL_BND_South_04 | BarrierWall_600 | (3700,0,0) | — | MI_DevBlue | ✅ | +| 22 | LVL_BND_South_05 | BarrierWall_600 | (4300,0,0) | — | MI_DevBlue | ✅ | +| 23 | LVL_BND_South_06 | BarrierWall_600 | (4900,0,0) | — | MI_DevBlue | ✅ | +| 24 | LVL_BND_South_07 | BarrierWall_600 | (5500,0,0) | — | MI_DevBlue | ✅ | +| 25 | LVL_BND_South_08 | BarrierWall_600 | (6100,0,0) | — | MI_DevBlue | ✅ | +| 26 | LVL_BND_South_09 | BarrierWall_600 | (6700,0,0) | — | MI_DevBlue | ✅ | +| 27 | LVL_BND_South_10 | BarrierWall_600 | (7300,0,0) | — | MI_DevBlue | ✅ | +| 28 | LVL_BND_South_11 | BarrierWall_600 | (7900,0,0) | — | MI_DevBlue | ✅ | +| 29 | LVL_Z7_STR_Building | Building_01 | (6400,800,0) | — | MI_DevGray | ✅ | +| 30 | LVL_Z7_STR_CollisionFront | Wall_400x300 | (6200,150,0) | — | MI_DevGray | ✅ | +| 31 | LVL_Z7_STR_CollisionFront2 | Wall_400x300 | (6600,150,0) | — | MI_DevGray | ✅ | +| 32 | LVL_Z7_STR_CollisionFront3 | Wall_400x300 | (7000,150,0) | — | MI_DevGray | ✅ | +| 33 | LVL_Z7_STR_CollisionSide | Wall_400x300 | (5750,400,0) | (0.00,90.00,0.00) | MI_DevGray | ✅ | +| 34 | LVL_Z7_STR_CollisionSide2 | Wall_400x300 | (5750,800,0) | (0.00,90.00,0.00) | MI_DevGray | ✅ | +| 35 | LVL_Z7_PROP_ClothesPole_01 | Beam_300 | (6100,190,800) | — | MI_DevWhite | ✅ | +| 36 | LVL_Z7_PROP_ClothesPole_02 | Beam_300 | (6500,190,1200) | — | MI_DevWhite | ✅ | +| 37 | LVL_Z7_PROP_ClothesPole_03 | Beam_300 | (6900,190,1600) | — | MI_DevWhite | ✅ | +| 38 | LVL_Z7_PROP_TrashCan | TrashCans_01 | (6000,140,0) | — | MI_DevGreen | ✅ | + +### GLOBAL 全局 + +共 64 个 Actor + +| # | Actor 名称 | 资产 | 位置 | 缩放 | 材质 | 状态 | +|---|-----------|------|------|------|------|------| +| 1 | LVL_BND_West_01 | Wall_400x300 | (0,200,0) | — | MI_DevRed | ✅ | +| 2 | LVL_BND_West_02 | Wall_400x300 | (0,600,0) | — | MI_DevRed | ✅ | +| 3 | LVL_BND_West_03 | Wall_400x300 | (0,1000,0) | — | MI_DevRed | ✅ | +| 4 | LVL_BND_West_04 | Wall_400x300 | (0,1400,0) | — | MI_DevRed | ✅ | +| 5 | LVL_BND_West_05 | Wall_400x300 | (0,1800,0) | — | MI_DevRed | ✅ | +| 6 | LVL_BND_West_06 | Wall_400x300 | (0,2200,0) | — | MI_DevRed | ✅ | +| 7 | LVL_BND_West_07 | Wall_400x300 | (0,2600,0) | — | MI_DevRed | ✅ | +| 8 | LVL_BND_West_08 | Wall_400x300 | (0,3000,0) | — | MI_DevRed | ✅ | +| 9 | LVL_BND_West_09 | Wall_400x300 | (0,3400,0) | — | MI_DevRed | ✅ | +| 10 | LVL_BND_West_10 | Wall_400x300 | (0,3800,0) | — | MI_DevRed | ✅ | +| 11 | LVL_BND_West_11 | Wall_400x300 | (0,4200,0) | — | MI_DevRed | ✅ | +| 12 | LVL_BND_West_12 | Wall_400x300 | (0,4600,0) | — | MI_DevRed | ✅ | +| 13 | LVL_BND_West_13 | Wall_400x300 | (0,5000,0) | — | MI_DevRed | ✅ | +| 14 | LVL_BND_West_14 | Wall_400x300 | (0,5400,0) | — | MI_DevRed | ✅ | +| 15 | LVL_BND_West_15 | Wall_400x300 | (0,5800,0) | — | MI_DevRed | ✅ | +| 16 | LVL_BND_East_01 | BarrierWall_600 | (8000,200,0) | — | MI_DevBlue | ✅ | +| 17 | LVL_BND_East_02 | BarrierWall_600 | (8000,600,0) | — | MI_DevBlue | ✅ | +| 18 | LVL_BND_East_03 | BarrierWall_600 | (8000,1000,0) | — | MI_DevBlue | ✅ | +| 19 | LVL_BND_East_04 | BarrierWall_600 | (8000,1400,0) | — | MI_DevBlue | ✅ | +| 20 | LVL_BND_East_05 | BarrierWall_600 | (8000,1800,0) | — | MI_DevBlue | ✅ | +| 21 | LVL_BND_East_06 | BarrierWall_600 | (8000,2200,0) | — | MI_DevBlue | ✅ | +| 22 | LVL_BND_East_07 | BarrierWall_600 | (8000,2600,0) | — | MI_DevBlue | ✅ | +| 23 | LVL_BND_East_08 | BarrierWall_600 | (8000,3000,0) | — | MI_DevBlue | ✅ | +| 24 | LVL_BND_East_09 | BarrierWall_600 | (8000,3400,0) | — | MI_DevBlue | ✅ | +| 25 | LVL_BND_East_10 | BarrierWall_600 | (8000,3800,0) | — | MI_DevBlue | ✅ | +| 26 | LVL_BND_East_11 | BarrierWall_600 | (8000,4200,0) | — | MI_DevBlue | ✅ | +| 27 | LVL_BND_East_12 | BarrierWall_600 | (8000,4600,0) | — | MI_DevBlue | ✅ | +| 28 | LVL_BND_East_13 | BarrierWall_600 | (8000,5000,0) | — | MI_DevBlue | ✅ | +| 29 | LVL_BND_East_14 | BarrierWall_600 | (8000,5400,0) | — | MI_DevBlue | ✅ | +| 30 | LVL_BND_East_15 | BarrierWall_600 | (8000,5800,0) | — | MI_DevBlue | ✅ | +| 31 | LVL_BND_North_01 | Wall_400x300 | (200,6000,0) | — | MI_DevBlue | ✅ | +| 32 | LVL_BND_North_02 | Wall_400x300 | (600,6000,0) | — | MI_DevBlue | ✅ | +| 33 | LVL_BND_North_03 | Wall_400x300 | (1000,6000,0) | — | MI_DevBlue | ✅ | +| 34 | LVL_BND_North_04 | Wall_400x300 | (1400,6000,0) | — | MI_DevBlue | ✅ | +| 35 | LVL_BND_North_05 | Wall_400x300 | (1800,6000,0) | — | MI_DevBlue | ✅ | +| 36 | LVL_BND_North_06 | Wall_400x300 | (2200,6000,0) | — | MI_DevBlue | ✅ | +| 37 | LVL_BND_North_07 | Wall_400x300 | (2600,6000,0) | — | MI_DevBlue | ✅ | +| 38 | LVL_BND_North_08 | Wall_400x300 | (3000,6000,0) | — | MI_DevBlue | ✅ | +| 39 | LVL_BND_North_09 | Wall_400x300 | (3400,6000,0) | — | MI_DevBlue | ✅ | +| 40 | LVL_BND_North_10 | Wall_400x300 | (3800,6000,0) | — | MI_DevBlue | ✅ | +| 41 | LVL_BND_North_11 | Wall_400x300 | (4200,6000,0) | — | MI_DevBlue | ✅ | +| 42 | LVL_BND_North_12 | Wall_400x300 | (4600,6000,0) | — | MI_DevBlue | ✅ | +| 43 | LVL_BND_North_13 | Wall_400x300 | (5000,6000,0) | — | MI_DevBlue | ✅ | +| 44 | LVL_BND_North_14 | Wall_400x300 | (5400,6000,0) | — | MI_DevBlue | ✅ | +| 45 | LVL_BND_North_15 | Wall_400x300 | (5800,6000,0) | — | MI_DevBlue | ✅ | +| 46 | LVL_BND_North_16 | Wall_400x300 | (6200,6000,0) | — | MI_DevBlue | ✅ | +| 47 | LVL_BND_North_17 | Wall_400x300 | (6600,6000,0) | — | MI_DevBlue | ✅ | +| 48 | LVL_BND_North_18 | Wall_400x300 | (7000,6000,0) | — | MI_DevBlue | ✅ | +| 49 | LVL_BND_North_19 | Wall_400x300 | (7400,6000,0) | — | MI_DevBlue | ✅ | +| 50 | LVL_BND_North_20 | Wall_400x300 | (7800,6000,0) | — | MI_DevBlue | ✅ | +| 51 | LVL_BND_South_01 | BarrierWall_600 | (1900,0,0) | — | MI_DevBlue | ✅ | +| 52 | LVL_BND_South_02 | BarrierWall_600 | (2500,0,0) | — | MI_DevBlue | ✅ | +| 53 | LVL_BND_South_03 | BarrierWall_600 | (3100,0,0) | — | MI_DevBlue | ✅ | +| 54 | LVL_BND_South_04 | BarrierWall_600 | (3700,0,0) | — | MI_DevBlue | ✅ | +| 55 | LVL_BND_South_05 | BarrierWall_600 | (4300,0,0) | — | MI_DevBlue | ✅ | +| 56 | LVL_BND_South_06 | BarrierWall_600 | (4900,0,0) | — | MI_DevBlue | ✅ | +| 57 | LVL_BND_South_07 | BarrierWall_600 | (5500,0,0) | — | MI_DevBlue | ✅ | +| 58 | LVL_BND_South_08 | BarrierWall_600 | (6100,0,0) | — | MI_DevBlue | ✅ | +| 59 | LVL_BND_South_09 | BarrierWall_600 | (6700,0,0) | — | MI_DevBlue | ✅ | +| 60 | LVL_BND_South_10 | BarrierWall_600 | (7300,0,0) | — | MI_DevBlue | ✅ | +| 61 | LVL_BND_South_11 | BarrierWall_600 | (7900,0,0) | — | MI_DevBlue | ✅ | +| 62 | LVL_Global_DirectionalLight | | (0,0,500) | — | — | ✅ | +| 63 | LVL_Global_SkyLight | | (0,0,0) | — | — | ✅ | +| 64 | LVL_PlayerStart | | (500,720,0) | — | — | ✅ | + +## 三、资产使用统计 + +| 资产名 | 使用次数 | +|--------|---------| +| Wall_400x300 | 95 | +| BarrierWall_600 | 46 | +| Cube | 21 | +| Floor_1000x1000 | 15 | +| CirclePlatform | 12 | +| Cylinder | 9 | +| Beam_300 | 5 | +| BarrierWall_200 | 5 | +| Wall_400x100 | 4 | +| Floor_300x400 | 4 | +| WoodenBox_Small | 4 | +| Wall_200x300 | 4 | +| TrashCans_01 | 3 | +| Fence_Small_400 | 3 | +| RoadLamp_01 | 3 | +| WallDoor_200x300 | 2 | +| Car01 | 2 | +| Monitor_01 | 2 | +| Floor_200x300 | 2 | +| RotativeDoor_01 | 1 | +| WallWindow_400x300 | 1 | +| WallWindowSmall_200x300 | 1 | +| Bucket_01 | 1 | +| Barrel | 1 | +| SimpleTable_01 | 1 | +| BedSingle | 1 | +| SimpleTable_02 | 1 | +| Wall_100x300 | 1 | +| DisplayPanels_400x200 | 1 | +| WallDoorGarage_400x300 | 1 | +| GarageDoorOpen_01 | 1 | +| Container_Normal | 1 | +| Tree_01 | 1 | +| WoodenPallet_01 | 1 | +| WoodenBox_Normal | 1 | +| FakeWindowsFrame | 1 | +| Building_01 | 1 | + +## 四、缩放记录 + +| Actor 名称 | 资产 | 缩放 | 实际尺寸 (cm) | +|-----------|------|------|-------------| +| LVL_Z1_STR_Floor | Floor_1000x1000 | (1.00,0.80,1.00) | 1000×800×10 | +| LVL_Z2_STR_Floor | Floor_1000x1000 | (0.60,0.60,1.00) | 600×600×10 | +| LVL_Z3_STR_Floor_01 | Floor_1000x1000 | (1.00,0.50,1.00) | 1000×500×10 | +| LVL_Z3_STR_Floor_02 | Floor_1000x1000 | (1.00,0.50,1.00) | 1000×500×10 | +| LVL_Z3_STR_Floor_03 | Floor_1000x1000 | (1.00,0.50,1.00) | 1000×500×10 | +| LVL_Z3_STR_Floor_04 | Floor_1000x1000 | (1.00,0.50,1.00) | 1000×500×10 | +| LVL_Z3_STR_Floor_05 | Floor_1000x1000 | (1.00,0.50,1.00) | 1000×500×10 | +| LVL_Z4_STR_Floor_01 | Floor_1000x1000 | (1.50,1.20,1.00) | 1500×1200×10 | +| LVL_Z5_STR_Floor_01 | Floor_1000x1000 | (0.30,1.00,1.00) | 300×1000×10 | +| LVL_Z5_STR_Floor_02 | Floor_1000x1000 | (0.30,1.00,1.00) | 300×1000×10 | +| LVL_Z6_STR_GroundSouth | Floor_1000x1000 | (1.50,0.35,1.00) | 1500×350×10 | +| LVL_Z6_STR_GroundEast | Floor_1000x1000 | (0.15,0.80,1.00) | 150×800×10 | +| LVL_Z6_STR_GroundWest | Floor_1000x1000 | (0.15,0.80,1.00) | 150×800×10 | +| LVL_Z6_STR_Water | Floor_1000x1000 | (1.20,0.80,0.50) | 1200×800×5 | +| LVL_Z1_STR_CourtyardFloor | Floor_1000x1000 | (1.00,0.80,1.00) | 1000×800×10 | +| LVL_Z1_PROP_OldBicycle | Car01 | (0.20,0.20,0.20) | (默认尺寸未知) | +| LVL_Z1_PROP_ClothesPole_Pole1 | Cylinder | (0.05,0.05,3.60) | 5×5×360 | +| LVL_Z1_PROP_ClothesPole_Pole2 | Cylinder | (0.05,0.05,3.60) | 5×5×360 | +| LVL_Z1_PROP_DoorMat | Cube | (0.60,0.40,0.02) | 60×40×2 | +| LVL_Z1_PROP_Fridge | Barrel | (0.30,0.30,1.60) | (默认尺寸未知) | +| LVL_Z1_PROP_Calendar | Cube | (0.30,0.02,0.40) | 30×2×40 | +| LVL_Z1_PROP_TVStand | SimpleTable_02 | (0.85,0.75,0.67) | (默认尺寸未知) | +| LVL_Z1_INTR_01_Fridge | Cube | (0.30,0.30,0.30) | 30×30×30 | +| LVL_Z1_INTR_02_Gate | Cube | (0.30,0.30,0.30) | 30×30×30 | +| LVL_Z1_INTR_06_TV | Cube | (0.30,0.30,0.30) | 30×30×30 | +| LVL_Z1_COLL_10_CatEyeMarble | CirclePlatform | (0.03,0.03,0.03) | (默认尺寸未知) | +| LVL_Z3_PROP_PhoneBooth | Cube | (0.80,0.80,2.20) | 80×80×220 | +| LVL_Z3_PROP_Bicycle | Car01 | (0.20,0.20,0.20) | (默认尺寸未知) | +| LVL_Z3_PROP_ClothesPolePole | Cylinder | (0.05,0.05,3.60) | 5×5×360 | +| LVL_Z3_PROP_SewerCover | CirclePlatform | (0.12,0.12,0.02) | (默认尺寸未知) | +| LVL_Z3_PROP_Graffiti | Cube | (1.20,0.05,0.80) | 120×5×80 | +| LVL_Z3_PROP_PoleWest | Cylinder | (0.04,0.04,12.00) | 4×4×1200 | +| LVL_Z3_PROP_PoleEast | Cylinder | (0.04,0.04,12.00) | 4×4×1200 | +| LVL_Z3_INTR_04_PhoneBooth | Cube | (0.30,0.30,0.30) | 30×30×30 | +| LVL_Z3_INTR_09_Graffiti | Cube | (0.30,0.30,0.30) | 30×30×30 | +| LVL_Z3_COLL_08_IceFlowerMarble | CirclePlatform | (0.03,0.03,0.03) | (默认尺寸未知) | +| LVL_Z2_PROP_Counter | Cube | (2.00,0.60,0.90) | 200×60×90 | +| LVL_Z2_PROP_ShelfEast_01 | Fence_Small_400 | (1.00,1.00,1.80) | 400×5×180 | +| LVL_Z2_PROP_ShelfEast_02 | Fence_Small_400 | (1.00,1.00,1.80) | 400×5×180 | +| LVL_Z2_PROP_ShelfSouth | Fence_Small_400 | (1.00,1.00,1.80) | 400×5×180 | +| LVL_Z2_PROP_Freezer | Container_Normal | (0.25,0.15,0.40) | (默认尺寸未知) | +| LVL_Z2_PROP_SmallTV | Monitor_01 | (0.60,0.60,0.60) | (默认尺寸未知) | +| LVL_Z2_PROP_Signboard | Cube | (3.00,0.05,0.40) | 300×5×40 | +| LVL_Z2_PROP_CardRack | Cube | (0.40,0.20,0.30) | 40×20×30 | +| LVL_Z2_INTR_05_ShopOwner | Cube | (0.30,0.30,0.30) | 30×30×30 | +| LVL_Z2_INTR_07_SnackShelf | Cube | (0.30,0.30,0.30) | 30×30×30 | +| LVL_Z2_COLL_09_BouncyBall | CirclePlatform | (0.03,0.03,0.03) | (默认尺寸未知) | +| LVL_Z4_PROP_BigTree | Tree_01 | (1.20,1.20,1.20) | (默认尺寸未知) | +| LVL_Z4_PROP_Puddle | Cube | (1.20,0.80,0.01) | 120×80×1 | +| LVL_Z4_PROP_MarbleCircle | CirclePlatform | (0.16,0.16,0.01) | (默认尺寸未知) | +| LVL_Z4_INTR_03_BlueMarble | Cube | (0.30,0.30,0.30) | 30×30×30 | +| LVL_Z4_INTR_08_SmallStone | Cube | (0.30,0.30,0.30) | 30×30×30 | +| LVL_Z4_COLL_01_BlueMarble | CirclePlatform | (0.03,0.03,0.03) | (默认尺寸未知) | +| LVL_Z4_COLL_03_SmallStone | CirclePlatform | (0.03,0.03,0.03) | (默认尺寸未知) | +| LVL_Z4_COLL_04_LuZhishenCard | CirclePlatform | (0.03,0.03,0.03) | (默认尺寸未知) | +| LVL_Z5_PROP_SpiderWeb | Cube | (0.30,0.30,0.01) | 30×30×1 | +| LVL_Z5_PROP_FlowerPot | Cylinder | (0.20,0.20,0.25) | 20×20×25 | +| LVL_Z5_PROP_Moss | Cube | (0.60,0.40,0.01) | 60×40×1 | +| LVL_Z5_INTR_10_WasteBox | Cube | (0.30,0.30,0.30) | 30×30×30 | +| LVL_Z5_COLL_02_RedMarble | CirclePlatform | (0.03,0.03,0.03) | (默认尺寸未知) | +| LVL_Z6_PROP_Reeds_S1~5 | Cylinder | (0.08,0.08,2.00) | 8×8×200 | +| LVL_Z6_PROP_Reeds_S2_1~5 | Cylinder | (0.08,0.08,2.00) | 8×8×200 | +| LVL_Z6_PROP_Reeds_E_1~3 | Cylinder | (0.08,0.08,1.60) | 8×8×160 | +| LVL_Z6_PROP_LilyPad_1~4 | CirclePlatform | (0.06,0.06,0.01) | (默认尺寸未知) | +| LVL_Z6_PROP_Frog | Cube | (0.05,0.05,0.04) | 5×5×4 | +| LVL_Z6_COLL_05_CandyWrapper | CirclePlatform | (0.03,0.03,0.03) | (默认尺寸未知) | +| LVL_Z6_COLL_06_Eraser | CirclePlatform | (0.03,0.03,0.03) | (默认尺寸未知) | +| LVL_Z7_STR_CollisionSide | Wall_400x300 | (0.00,90.00,0.00) | 0×1800×0 | +| LVL_Z7_STR_CollisionSide2 | Wall_400x300 | (0.00,90.00,0.00) | 0×1800×0 | diff --git a/tools/level-builder/parsers/__init__.py b/tools/level-builder/parsers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tools/level-builder/parsers/build_guide_parser.py b/tools/level-builder/parsers/build_guide_parser.py new file mode 100644 index 0000000..8ee0c0f --- /dev/null +++ b/tools/level-builder/parsers/build_guide_parser.py @@ -0,0 +1,772 @@ +"""搭建指南 Markdown 解析器。 + +解析 docs/technical/关卡-v01-搭建指南.md,输出统一的 Actor 列表。 + +搭建指南的表格格式(4 种变体 + 特殊表格): + - 结构体表: # / Actor名称 / 资产 / 位置 / [旋转] / [缩放] / 材质 + - 布景表: # / Actor名称 / 资产 / 位置 / [缩放] / 材质 / 说明 + - 交互物表: # / Actor名称 / 位置 / 触发半径 / [交互类型] / 引用 + - 收集品表: # / Actor名称 / 位置 / 稀有度 / 引用 + - 边界表: # / Actor名称 / 资产 / 位置 / [旋转] / [缩放] / 材质 + - 光照表: # / Actor名称 / 类型 / 位置 / 参数 +""" + +import json +import re +import logging +from pathlib import Path +from dataclasses import dataclass, field, asdict +from typing import Optional + +from parsers.markdown_table import ( + parse_table, + parse_location, + parse_rotation, + parse_scale, + clean_cell, +) + +logger = logging.getLogger("level_builder.parser") + +# ============================================================ +# 数据结构 +# ============================================================ + +@dataclass +class ActorData: + """单个 Actor 的完整规格。""" + actor_name: str + asset_key: str = "" + asset_type: str = "static_mesh" # static_mesh | player_start | directional_light | sky_light | point_light + category: str = "" # STR | PROP | INTR | COLL | BND | LGT | PLAY + zone_id: str = "" # Z1-Z7 | GLOBAL + location: tuple = (0.0, 0.0, 0.0) + rotation: tuple = (0.0, 0.0, 0.0) + scale: tuple = (1.0, 1.0, 1.0) + material: str = "" + folder: str = "" + note: str = "" + trigger_radius: float = 0.0 + interact_type: str = "" + rarity: str = "" + source_ref: str = "" + + +# ============================================================ +# 标题/上下文检测 +# ============================================================ + +# 区域标题匹配:### C1. Z1 — 家(Home) +ZONE_HEADING = re.compile( + r'###\s+C\d+\.\s+(Z\d+)\s*[—\-–]\s*(.+?)(?:((.+)))?$' +) + +# 分类子标题匹配:#### C1.1 结构体(Structure) +CATEGORY_HEADING = re.compile( + r'####\s+C\d+\.\d+\s+(结构体|布景|交互物|收集品|布景物)' +) + +# Phase 标题 +PHASE_HEADING = re.compile(r'^##\s+(二|三|四|五|六|七|八)') + +# 边界区域标题 +BOUNDARY_HEADING = re.compile(r'####\s+(西边界|东边界|北边界|南边界)') + +# 全局物件标题 +GLOBAL_HEADING = re.compile(r'###\s+G-(\d+|E\d+)\s+(.+)') + +# 光照标题 +LIGHT_HEADING = re.compile(r'###\s+D\d+\s+(.+)') + +# 地面子标题 +FLOOR_HEADING = re.compile(r'####\s+Z\d+\s+(.+?)\s+地面') + +CATEGORY_MAP = { + "结构体": "STR", + "布景": "PROP", + "布景物": "PROP", + "交互物": "INTR", + "交互物标记": "INTR", + "收集品": "COLL", + "收集品标记": "COLL", +} + +ZONE_ID_MAP = { + "Z1": "Z1", "Z2": "Z2", "Z3": "Z3", + "Z4": "Z4", "Z5": "Z5", "Z6": "Z6", "Z7": "Z7", +} + + +# ============================================================ +# 核心解析逻辑 +# ============================================================ + +class BuildGuideParser: + """搭建指南解析器。""" + + def __init__(self): + self.actors: list[ActorData] = [] + self.current_zone = "" + self.current_category = "" + self.current_phase = "" + self.metadata = {} + + def parse_file(self, filepath: str) -> dict: + """解析搭建指南文件,返回完整的关卡数据。""" + path = Path(filepath) + if not path.exists(): + raise FileNotFoundError(f"搭建指南文件不存在: {filepath}") + + text = path.read_text(encoding="utf-8") + return self.parse_text(text) + + def parse_text(self, text: str) -> dict: + """解析搭建指南文本。""" + lines = text.split("\n") + + # 解析全局参数(第〇章) + self._parse_global_info(lines) + + # 解析资产映射表(第一章)— 可选,用于验证 + # 逐 Phase 解析 + self._parse_phase_ground(lines) + self._parse_phase_boundaries(lines) + self._parse_phase_zones(lines) + self._parse_phase_global_objects(lines) + self._parse_phase_lighting(lines) + + # 添加 Player Start + self._add_player_start() + + # 构建输出 + result = { + "metadata": self.metadata, + "actors": [asdict(a) for a in self.actors], + "summary": self._build_summary(), + } + return result + + # ---------------------------------------------------------- + # 全局参数 + # ---------------------------------------------------------- + def _parse_global_info(self, lines: list[str]): + """解析场景全局参数。""" + self.metadata = { + "source": "关卡-v01-搭建指南.md", + "scene_size": [8000, 6000], + "ground_z": 0, + "character_height": 120, + "camera_height": 100, + } + + # ---------------------------------------------------------- + # Phase B — 地面 + # ---------------------------------------------------------- + def _parse_phase_ground(self, lines: list[str]): + """解析 Phase B 地面铺设表格。""" + text = "\n".join(lines) + # 找到 Phase B 区域 + b_start = self._find_section_start(lines, "Phase B") + b_end = self._find_section_start(lines, "Phase C") + if b_start < 0: + return + if b_end < 0: + b_end = len(lines) + + section_text = "\n".join(lines[b_start:b_end]) + + # 地面子区域标题:#### Z1 家 地面(MI_DevGray) + floor_pattern = re.compile( + r'####\s+Z(\d+)\s+\S+\s+地面(?:((.+?)))?' + ) + + current_zone = "" + current_material = "" + section_lines = lines[b_start:b_end] + + i = 0 + while i < len(section_lines): + line = section_lines[i].strip() + + # 检测地面子区域 + fm = floor_pattern.match(line) + if fm: + current_zone = f"Z{fm.group(1)}" + current_material = fm.group(2) or "" + i += 1 + continue + + # 检测水面区域 + if '水面' in line and current_zone: + current_material = "MI_DevSkyBlue" + i += 1 + continue + + # 检测表格 + if '|' in line and '#' in line: + table_lines = [] + while i < len(section_lines) and '|' in section_lines[i]: + table_lines.append(section_lines[i]) + i += 1 + rows = parse_table(table_lines) + if rows: + for row in rows: + actor = self._parse_floor_row(row, current_zone, current_material) + if actor: + self.actors.append(actor) + continue + + i += 1 + + def _parse_floor_row(self, row: dict, zone: str, default_material: str) -> Optional[ActorData]: + """解析地面表格行。""" + name = clean_cell(row.get("Actor 名称", row.get("Actor名称", ""))) + if not name: + return None + + asset_key = clean_cell(row.get("资产", "")) + location = parse_location(row.get("位置 (X,Y,Z)", row.get("位置", ""))) + scale = parse_scale(row.get("缩放", "—")) + material = clean_cell(row.get("材质", "")) + if not material: + material = default_material + + return ActorData( + actor_name=name, + asset_key=asset_key, + asset_type="static_mesh", + category="STR", + zone_id=zone, + location=location, + scale=scale, + material=material, + folder=self._get_folder(zone, "STR"), + ) + + # ---------------------------------------------------------- + # Phase B — 边界 + # ---------------------------------------------------------- + def _parse_phase_boundaries(self, lines: list[str]): + """解析 Phase B 边界围挡。""" + b_start = self._find_section_start(lines, "放置边界围挡") + b_end = self._find_section_start(lines, "Phase C") + if b_start < 0: + return + if b_end < 0: + b_end = len(lines) + + section_lines = lines[b_start:b_end] + i = 0 + while i < len(section_lines): + line = section_lines[i].strip() + + # 边界子区域标题 + bm = BOUNDARY_HEADING.match(line) + + # 检测表格 + if '|' in line: + table_lines = [] + while i < len(section_lines) and '|' in section_lines[i]: + table_lines.append(section_lines[i]) + i += 1 + rows = parse_table(table_lines) + if rows: + for row in rows: + actors = self._parse_boundary_row(row) + self.actors.extend(actors) + continue + + i += 1 + + def _parse_boundary_row(self, row: dict) -> list[ActorData]: + """解析边界表格行,处理范围格式如 '1-15 | LVL_BND_East_01~15'。""" + name_col = row.get("Actor 名称", row.get("Actor名称", "")) + name = clean_cell(name_col) + + # 处理范围格式:名称中含 ~ 或编号含 - + if '~' in name: + return self._expand_range_row(row, name) + + asset_key = clean_cell(row.get("资产", "")) + location = parse_location(row.get("位置 (X,Y,Z)", row.get("位置", ""))) + rotation = parse_rotation(row.get("旋转 (Pitch,Yaw,Roll)", row.get("旋转", "(0,0,0)"))) + scale = parse_scale(row.get("缩放", "—")) + material = clean_cell(row.get("材质", "")) + + actor = ActorData( + actor_name=name, + asset_key=asset_key, + category="BND", + zone_id="GLOBAL", + location=location, + rotation=rotation, + scale=scale, + material=material, + folder=self._get_folder("GLOBAL", "BND"), + ) + return [actor] + + def _expand_range_row(self, row: dict, name: str) -> list[ActorData]: + """展开范围格式行。如 'LVL_BND_East_01~15' → 15 个 Actor。""" + asset_key = clean_cell(row.get("资产", "")) + rotation = parse_rotation(row.get("旋转 (Pitch,Yaw,Roll)", row.get("旋转", "(0,0,0)"))) + scale = parse_scale(row.get("缩放", "—")) + material = clean_cell(row.get("材质", "")) + + # 解析名称范围:LVL_BND_East_01~15 + m = re.match(r'(.+?)_(\d+)~(\d+)', name) + if not m: + return [] + + prefix = m.group(1) + start = int(m.group(2)) + end = int(m.group(3)) + + # 解析位置表达式 — 格式: (X, Y_expr, Z) n=start~end + # 例: (8000, 200+400n, 0) n=0~14 + loc_col = row.get("位置 (X,Y,Z)", row.get("位置", "")) + loc_col = clean_cell(loc_col) + + # 提取 n 的范围 + n_match = re.search(r'n\s*=\s*(\d+)~(\d+)', loc_col) + n_start = int(n_match.group(1)) if n_match else 0 + n_end = int(n_match.group(2)) if n_match else (end - start) + # 去掉 n=xx~yy 后缀以便解析坐标 + loc_clean = re.sub(r'\s*n\s*=\s*\d+~\d+\s*', '', loc_col).strip() + + # 提取三个坐标表达式 + coord_match = re.match(r'\((.+?)\s*,\s*(.+?)\s*,\s*(.+?)\)', loc_clean) + if not coord_match: + return [] + + x_expr = coord_match.group(1).strip() + y_expr = coord_match.group(2).strip() + z_expr = coord_match.group(3).strip() + + actors = [] + for idx, n in enumerate(range(n_start, n_end + 1)): + x = self._eval_coord_expr(x_expr, n) + y = self._eval_coord_expr(y_expr, n) + z = self._eval_coord_expr(z_expr, n) + + actor_num = start + idx + actor_name = f"{prefix}_{actor_num:02d}" + actor = ActorData( + actor_name=actor_name, + asset_key=asset_key, + category="BND", + zone_id="GLOBAL", + location=(x, y, z), + rotation=rotation, + scale=scale, + material=material, + folder=self._get_folder("GLOBAL", "BND"), + ) + actors.append(actor) + + return actors + + def _eval_coord_expr(self, expr: str, n: int) -> float: + """计算坐标表达式。如 '200+400n' → 200+400*n。""" + expr = expr.strip() + # 简单情况:纯数字 + try: + return float(expr) + except ValueError: + pass + + # 含 n 的表达式:200+400n + expr = expr.replace('n', f'*{n}') + # 处理连续运算符:*+→+, *-→- + expr = expr.replace('*+', '+').replace('*-', '-') + + try: + # 安全计算简单算术 + result = eval(expr) # 受限输入,仅数字和基本运算 + return float(result) + except Exception: + return 0.0 + + # ---------------------------------------------------------- + # Phase C — 逐区域搭建 + # ---------------------------------------------------------- + def _parse_phase_zones(self, lines: list[str]): + """解析 Phase C 逐区域搭建。""" + c_start = self._find_section_start(lines, "逐区域搭建") + c_end = self._find_section_start(lines, "Phase C — 全局物件") + if c_start < 0: + c_start = self._find_section_start(lines, "全局物件") + if c_start < 0: + return + if c_end < 0: + c_end = len(lines) + + section_lines = lines[c_start:c_end] + current_zone = "" + current_category = "" + + i = 0 + while i < len(section_lines): + line = section_lines[i].strip() + + # 检测区域标题 + zm = ZONE_HEADING.match(line) + if zm: + current_zone = zm.group(1) + i += 1 + continue + + # 检测分类标题 + cm = CATEGORY_HEADING.match(line) + if cm: + cat_name = cm.group(1) + current_category = CATEGORY_MAP.get(cat_name, "") + i += 1 + continue + + # 检测结构体子标题(如 "C1.1 结构体(Structure)") + sub_match = re.match(r'####\s+C\d+\.\d+\s+(结构体|布景|布景物|交互物|交互物标记|收集品|收集品标记)', line) + if sub_match: + cat_name = sub_match.group(1) + current_category = CATEGORY_MAP.get(cat_name, "") + i += 1 + continue + + # 处理表格 + if '|' in line: + table_lines = [] + while i < len(section_lines) and '|' in section_lines[i]: + table_lines.append(section_lines[i]) + i += 1 + rows = parse_table(table_lines) + if rows: + for row in rows: + actor = self._parse_zone_row(row, current_zone, current_category) + if actor: + self.actors.append(actor) + continue + + i += 1 + + def _parse_zone_row(self, row: dict, zone: str, category: str) -> Optional[ActorData]: + """解析区域内的 Actor 行。根据列内容判断表格类型。""" + name = clean_cell(row.get("Actor 名称", row.get("Actor名称", ""))) + if not name: + return None + + # 判断表格类型:有"资产"列 → 结构体/布景;有"触发半径" → 交互物;有"稀有度" → 收集品 + has_asset = "资产" in row and clean_cell(row.get("资产", "")) + has_trigger = "触发半径" in row or "触发半径 (cm)" in row + has_rarity = "稀有度" in row + + if has_trigger and not has_asset: + # 交互物表 + return self._parse_interactable_row(row, zone) + elif has_rarity and not has_asset: + # 收集品表 + return self._parse_collectible_row(row, zone) + else: + # 结构体/布景表 + return self._parse_structure_or_prop_row(row, zone, category) + + def _parse_structure_or_prop_row(self, row: dict, zone: str, category: str) -> Optional[ActorData]: + """解析结构体或布景表格行。""" + name = clean_cell(row.get("Actor 名称", row.get("Actor名称", ""))) + asset_key = clean_cell(row.get("资产", "")) + location = parse_location( + row.get("位置 (X,Y,Z)", row.get("位置", "")) + ) + + # 旋转:结构体表可能有,布景表可能没有 + rot_col = row.get("旋转 (Pitch,Yaw,Roll)", row.get("旋转", "")) + rotation = parse_rotation(rot_col) if rot_col else (0.0, 0.0, 0.0) + + # 缩放 + scale = parse_scale(row.get("缩放", "—")) + + # 材质 + material = clean_cell(row.get("材质", "")) + if material in ('—', '–', '-'): + material = "" + + # 说明 + note = clean_cell(row.get("说明", "")) + + if not category: + category = "STR" + + return ActorData( + actor_name=name, + asset_key=asset_key, + category=category, + zone_id=zone, + location=location, + rotation=rotation, + scale=scale, + material=material, + folder=self._get_folder(zone, category), + note=note, + ) + + def _parse_interactable_row(self, row: dict, zone: str) -> ActorData: + """解析交互物行。用占位 Cube 表示。""" + name = clean_cell(row.get("Actor 名称", row.get("Actor名称", ""))) + location = parse_location( + row.get("位置 (X,Y,Z)", row.get("位置", "")) + ) + trigger = row.get("触发半径", row.get("触发半径 (cm)", "150")) + try: + trigger_radius = float(trigger) + except (ValueError, TypeError): + trigger_radius = 150.0 + + ref = clean_cell(row.get("引用", "")) + interact_type = clean_cell(row.get("交互类型", "")) + + return ActorData( + actor_name=name, + asset_key="Cube", + category="INTR", + zone_id=zone, + location=location, + scale=(0.3, 0.3, 0.3), + material="MI_DevYellow", + folder=self._get_folder(zone, "INTR"), + trigger_radius=trigger_radius, + interact_type=interact_type, + source_ref=ref, + note="交互物占位标记", + ) + + def _parse_collectible_row(self, row: dict, zone: str) -> ActorData: + """解析收集品行。用占位 Sphere/Cube 表示。""" + name = clean_cell(row.get("Actor 名称", row.get("Actor名称", ""))) + location = parse_location( + row.get("位置 (X,Y,Z)", row.get("位置", "")) + ) + rarity = clean_cell(row.get("稀有度", "普通")) + ref = clean_cell(row.get("引用", "")) + + # 稀有用金色,普通用白色 + material = "MI_DevYellow" if rarity == "稀有" else "MI_DevWhite" + + return ActorData( + actor_name=name, + asset_key="CirclePlatform", + category="COLL", + zone_id=zone, + location=location, + scale=(0.03, 0.03, 0.03), + material=material, + folder=self._get_folder(zone, "COLL"), + rarity=rarity, + source_ref=ref, + note="收集品占位标记", + ) + + # ---------------------------------------------------------- + # Phase C — 全局物件 + # ---------------------------------------------------------- + def _parse_phase_global_objects(self, lines: list[str]): + """解析全局物件(路灯、垃圾桶等)。""" + g_start = self._find_section_start(lines, "全局物件") + g_end = self._find_section_start(lines, "Phase D") + if g_start < 0: + return + if g_end < 0: + g_end = len(lines) + + section_lines = lines[g_start:g_end] + i = 0 + while i < len(section_lines): + line = section_lines[i].strip() + if '|' in line: + table_lines = [] + while i < len(section_lines) and '|' in section_lines[i]: + table_lines.append(section_lines[i]) + i += 1 + rows = parse_table(table_lines) + if rows: + for row in rows: + actor = self._parse_global_row(row) + if actor: + self.actors.append(actor) + continue + i += 1 + + def _parse_global_row(self, row: dict) -> Optional[ActorData]: + """解析全局物件行。""" + name = clean_cell(row.get("Actor 名称", row.get("Actor名称", ""))) + if not name: + return None + + asset_key = clean_cell(row.get("资产", "")) + location = parse_location(row.get("位置 (X,Y,Z)", row.get("位置", ""))) + material = clean_cell(row.get("材质", "")) + if material in ('—', '–', '-'): + material = "" + + # 从 Actor 名称推断类别 + category = "PROP" + if "_LGT_" in name: + category = "LGT" + elif "_PROP_" in name: + category = "PROP" + + zone_id = self._infer_zone_from_name(name) + + return ActorData( + actor_name=name, + asset_key=asset_key, + category=category, + zone_id=zone_id, + location=location, + material=material, + folder=self._get_folder(zone_id, category), + ) + + # ---------------------------------------------------------- + # Phase D — 光照 + # ---------------------------------------------------------- + def _parse_phase_lighting(self, lines: list[str]): + """解析光照配置。""" + d_start = self._find_section_start(lines, "Phase D") + d_end = self._find_section_start(lines, "Phase E") + if d_start < 0: + return + if d_end < 0: + d_end = len(lines) + + section_lines = lines[d_start:d_end] + + # 全局光源:DirectionalLight + SkyLight + self._parse_global_lights(section_lines) + + # 路灯点光源 + self._parse_street_lights(section_lines) + + def _parse_global_lights(self, lines: list[str]): + """解析全局光源表格。""" + text = "\n".join(lines) + # Directional Light 和 Sky Light + if "Directional Light" in text or "DirectionalLight" in text: + self.actors.append(ActorData( + actor_name="LVL_Global_DirectionalLight", + asset_key="", + asset_type="directional_light", + category="LGT", + zone_id="GLOBAL", + location=(0, 0, 500), + rotation=(-45, 315, 0), + folder=self._get_folder("GLOBAL", "LGT"), + note="色温~5500K暖白;从西南照射;强度中等", + )) + if "Sky Light" in text or "SkyLight" in text: + self.actors.append(ActorData( + actor_name="LVL_Global_SkyLight", + asset_key="", + asset_type="sky_light", + category="LGT", + zone_id="GLOBAL", + location=(0, 0, 0), + folder=self._get_folder("GLOBAL", "LGT"), + note="强度低-中;环境补光", + )) + + def _parse_street_lights(self, lines: list[str]): + """解析路灯点光源表格。""" + i = 0 + while i < len(lines): + line = lines[i].strip() + # 检测表格起始(含 | 的行) + if '|' in line: + table_lines = [] + while i < len(lines) and '|' in lines[i]: + table_lines.append(lines[i]) + i += 1 + + # 检查表格内容是否包含 Point Light + table_text = "\n".join(table_lines) + if "Point" in table_text or "point_light" in table_text.lower(): + rows = parse_table(table_lines) + for row in rows: + name = clean_cell(row.get("Actor 名称", row.get("Actor名称", ""))) + loc_col = row.get("位置 (X,Y,Z)", row.get("位置", "")) + location = parse_location(loc_col) + if name: + self.actors.append(ActorData( + actor_name=name, + asset_key="", + asset_type="point_light", + category="LGT", + zone_id="Z3", + location=location, + folder=self._get_folder("GLOBAL", "LGT"), + note="暖黄色,低强度", + )) + continue + i += 1 + + # ---------------------------------------------------------- + # Player Start + # ---------------------------------------------------------- + def _add_player_start(self): + """添加 Player Start Actor。""" + self.actors.append(ActorData( + actor_name="LVL_PlayerStart", + asset_key="", + asset_type="player_start", + category="PLAY", + zone_id="GLOBAL", + location=(500, 720, 0), + rotation=(0, 0, 0), + folder=self._get_folder("GLOBAL", "PLAY"), + note="Z1 院内院门内侧约60cm,面向+Y(北)", + )) + + # ---------------------------------------------------------- + # 辅助方法 + # ---------------------------------------------------------- + def _find_section_start(self, lines: list[str], keyword: str) -> int: + """找到包含关键词的标题行。""" + for i, line in enumerate(lines): + if keyword in line: + return i + return -1 + + def _infer_zone_from_name(self, name: str) -> str: + """从 Actor 名称推断区域 ID。""" + m = re.match(r'LVL_(Z\d+)_', name) + if m: + return m.group(1) + if 'BND' in name: + return "GLOBAL" + if 'Global' in name: + return "GLOBAL" + return "GLOBAL" + + def _get_folder(self, zone_id: str, category: str) -> str: + """获取 Outliner 文件夹路径。""" + from config.zone_config import get_folder_path + return get_folder_path(zone_id, category) + + def _build_summary(self) -> dict: + """构建解析摘要。""" + total = len(self.actors) + by_category = {} + by_zone = {} + asset_keys = set() + + for a in self.actors: + by_category[a.category] = by_category.get(a.category, 0) + 1 + by_zone[a.zone_id] = by_zone.get(a.zone_id, 0) + 1 + if a.asset_key: + asset_keys.add(a.asset_key) + + return { + "total_actors": total, + "by_category": by_category, + "by_zone": by_zone, + "unique_assets": len(asset_keys), + "asset_list": sorted(asset_keys), + } diff --git a/tools/level-builder/parsers/markdown_table.py b/tools/level-builder/parsers/markdown_table.py new file mode 100644 index 0000000..b3e0d2c --- /dev/null +++ b/tools/level-builder/parsers/markdown_table.py @@ -0,0 +1,186 @@ +"""通用 Markdown 管道表格解析器。 + +将 Markdown 表格文本解析为 list[dict],每个字典代表一行数据。 +支持中文列名,处理列数不一致的情况。 +""" + +import re +from typing import Optional + + +def parse_table(lines: list[str]) -> list[dict]: + """解析单个 Markdown 表格。 + + Args: + lines: 表格的文本行列表(包含表头、分隔行和数据行)。 + + Returns: + 列表,每个元素是一行数据的字典,key 为表头文本。 + 返回空列表如果输入不是有效表格。 + """ + if not lines: + return [] + + # 找到分隔行(包含 |---| 的行) + sep_idx = -1 + for i, line in enumerate(lines): + if re.match(r'\s*\|[\s\-:]+\|', line): + sep_idx = i + break + + if sep_idx < 1: + return [] # 没有有效的表头+分隔行 + + # 提取表头 + header_line = lines[sep_idx - 1] + headers = _split_row(header_line) + if not headers: + return [] + + # 提取数据行(分隔行之后的所有 | 开头的行) + data_rows = [] + for line in lines[sep_idx + 1:]: + stripped = line.strip() + if not stripped or not stripped.startswith('|'): + break # 表格结束 + cells = _split_row(stripped) + data_rows.append(cells) + + # 构建结果 + result = [] + for row in data_rows: + entry = {} + for j, header in enumerate(headers): + entry[header] = row[j] if j < len(row) else "" + result.append(entry) + + return result + + +def parse_all_tables(text: str) -> list[tuple[list[str], list[dict]]]: + """解析文本中的所有 Markdown 表格。 + + Args: + text: 完整的 Markdown 文本。 + + Returns: + 列表,每个元素为 (header, rows) 元组。 + header 为表头列表,rows 为 list[dict]。 + """ + results = [] + lines = text.split('\n') + i = 0 + + while i < len(lines): + # 寻找潜在的表格起始行(包含 | 的行) + if '|' in lines[i]: + # 收集连续的表格行 + table_lines = [] + while i < len(lines) and '|' in lines[i]: + table_lines.append(lines[i].strip()) + i += 1 + + # 尝试解析 + rows = parse_table(table_lines) + if rows: + # 提取表头 + for tl in table_lines: + if re.match(r'\s*\|[\s\-:]+\|', tl): + sep_idx = table_lines.index(tl) + if sep_idx > 0: + headers = _split_row(table_lines[sep_idx - 1]) + results.append((headers, rows)) + break + continue + i += 1 + + return results + + +def find_tables_in_section(text: str, section_start: int, section_end: int) -> list[list[dict]]: + """在文本的指定范围内找到所有表格。 + + Args: + text: 完整文本。 + section_start: 区域起始行号。 + section_end: 区域结束行号。 + + Returns: + 表格列表,每个表格是 list[dict]。 + """ + lines = text.split('\n') + section_lines = lines[section_start:section_end] + tables = [] + + i = 0 + while i < len(section_lines): + if '|' in section_lines[i]: + # 收集连续表格行 + table_lines = [] + while i < len(section_lines) and '|' in section_lines[i]: + table_lines.append(section_lines[i]) + i += 1 + rows = parse_table(table_lines) + if rows: + tables.append(rows) + continue + i += 1 + + return tables + + +def _split_row(line: str) -> list[str]: + """将 | 分隔的行拆分为单元格列表,去除首尾空格。""" + # 去除首尾空白 + line = line.strip() + # 按管道符分割 + if not line.startswith('|'): + return [] + if not line.endswith('|'): + # 有些行末尾可能没有 | + parts = line.split('|') + else: + parts = line.split('|') + + # 去除首尾空元素(管道符分割产生的) + cells = [c.strip() for c in parts] + # 去掉首尾空字符串 + while cells and cells[0] == '': + cells.pop(0) + while cells and cells[-1] == '': + cells.pop() + + return cells + + +def parse_location(text: str) -> tuple[float, float, float]: + """解析位置字符串 '(X,Y,Z)' 为三元组。""" + if not text: + return (0.0, 0.0, 0.0) + m = re.search(r'\(([-\d.]+)\s*[,,]\s*([-\d.]+)\s*[,,]\s*([-\d.]+)\)', text) + if m: + return (float(m.group(1)), float(m.group(2)), float(m.group(3))) + return (0.0, 0.0, 0.0) + + +def parse_rotation(text: str) -> tuple[float, float, float]: + """解析旋转字符串 '(P,Y,R)' 为三元组(度数)。""" + return parse_location(text) + + +def parse_scale(text: str) -> tuple[float, float, float]: + """解析缩放字符串 '(X,Y,Z)' 为三元组。'—' 或空返回 (1,1,1)。""" + if not text or text.strip() in ('—', '–', '-', '无', ''): + return (1.0, 1.0, 1.0) + return parse_location(text) + + +def clean_cell(text: str) -> str: + """清理单元格文本:去首尾空白、去反引号。""" + if not text: + return "" + text = text.strip() + # 去除 Markdown 反引号包裹 + if text.startswith('`') and text.endswith('`'): + text = text[1:-1] + return text.strip() diff --git a/tools/level-builder/report/__init__.py b/tools/level-builder/report/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tools/level-builder/report/report_generator.py b/tools/level-builder/report/report_generator.py new file mode 100644 index 0000000..76dbeeb --- /dev/null +++ b/tools/level-builder/report/report_generator.py @@ -0,0 +1,159 @@ +"""搭建报告生成器。 + +从解析数据和构建日志生成 Markdown 格式的搭建报告, +格式与 docs/technical/关卡-v01-搭建报告.md 一致。 +""" + +import json +from pathlib import Path +from datetime import datetime +from typing import Optional + + +def generate_report( + level_data: dict, + build_log: Optional[list[dict]] = None, + output_path: str = "", +) -> str: + """生成搭建报告 Markdown。 + + Args: + level_data: 解析器输出的关卡数据(含 metadata/actors/summary)。 + build_log: 构建日志(含每个 Actor 的成功/失败状态)。可选。 + output_path: 报告输出路径。为空则只返回字符串。 + + Returns: + Markdown 格式的搭建报告文本。 + """ + actors = level_data.get("actors", []) + summary = level_data.get("summary", {}) + metadata = level_data.get("metadata", {}) + + lines = [] + lines.append("# 白模搭建报告 — 自动生成") + lines.append("") + lines.append(f"> 生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M')}") + lines.append(f"> 数据来源: {metadata.get('source', '未知')}") + lines.append(f"> 场景尺寸: {metadata.get('scene_size', ['?','?'])[0]}cm × {metadata.get('scene_size', ['?','?'])[1]}cm") + lines.append("") + + # ---- 搭建概要 ---- + lines.append("## 一、搭建概要") + lines.append("") + + total = summary.get("total_actors", len(actors)) + by_category = summary.get("by_category", {}) + + lines.append(f"- **总 Actor 数**: {total}") + for cat in ["STR", "PROP", "INTR", "COLL", "BND", "LGT", "PLAY"]: + count = by_category.get(cat, 0) + if count > 0: + cat_name = {"STR": "结构体", "PROP": "布景", "INTR": "交互物", + "COLL": "收集品", "BND": "边界", "LGT": "光源", "PLAY": "PlayerStart"} + lines.append(f"- {cat_name.get(cat, cat)} ({cat}): {count}") + + if build_log: + ok = sum(1 for b in build_log if b.get("status") == "ok") + failed = sum(1 for b in build_log if b.get("status") != "ok") + lines.append(f"- 构建成功: {ok}") + lines.append(f"- 构建失败: {failed}") + + lines.append("") + + # ---- 逐区域对照 ---- + lines.append("## 二、逐区域对照") + lines.append("") + + by_zone = summary.get("by_zone", {}) + zone_names = { + "Z1": "家", "Z2": "小卖部", "Z3": "主街道", + "Z4": "空地", "Z5": "巷子", "Z6": "水塘边", "Z7": "老居民楼", + "GLOBAL": "全局", + } + + for zone_id in ["Z1", "Z2", "Z3", "Z4", "Z5", "Z6", "Z7", "GLOBAL"]: + zone_actors = [a for a in actors if a.get("zone_id") == zone_id] + if not zone_actors: + continue + + zone_name = zone_names.get(zone_id, zone_id) + lines.append(f"### {zone_id} {zone_name}") + lines.append("") + lines.append(f"共 {len(zone_actors)} 个 Actor") + lines.append("") + lines.append("| # | Actor 名称 | 资产 | 位置 | 缩放 | 材质 | 状态 |") + lines.append("|---|-----------|------|------|------|------|------|") + + for j, a in enumerate(zone_actors): + name = a.get("actor_name", "") + asset = a.get("asset_key", "—") + loc = a.get("location", [0, 0, 0]) + loc_str = f"({loc[0]:.0f},{loc[1]:.0f},{loc[2]:.0f})" + scale = a.get("scale", [1, 1, 1]) + if scale == [1, 1, 1] or scale == (1, 1, 1): + scale_str = "—" + else: + scale_str = f"({scale[0]:.2f},{scale[1]:.2f},{scale[2]:.2f})" + mat = a.get("material", "—") or "—" + + # 状态 + status = "✅" + if build_log: + log_entry = next((b for b in build_log if b.get("name") == name), None) + if log_entry: + status = "✅" if log_entry.get("status") == "ok" else f"❌ {log_entry.get('reason', '')}" + + lines.append(f"| {j+1} | {name} | {asset} | {loc_str} | {scale_str} | {mat} | {status} |") + + lines.append("") + + # ---- 资产使用统计 ---- + lines.append("## 三、资产使用统计") + lines.append("") + + asset_usage = {} + for a in actors: + key = a.get("asset_key", "") + if key: + asset_usage[key] = asset_usage.get(key, 0) + 1 + + lines.append("| 资产名 | 使用次数 |") + lines.append("|--------|---------|") + for key in sorted(asset_usage.keys(), key=lambda k: -asset_usage[k]): + lines.append(f"| {key} | {asset_usage[key]} |") + lines.append("") + + # ---- 缩放记录 ---- + lines.append("## 四、缩放记录") + lines.append("") + lines.append("| Actor 名称 | 资产 | 缩放 | 实际尺寸 (cm) |") + lines.append("|-----------|------|------|-------------|") + + for a in actors: + scale = a.get("scale", [1, 1, 1]) + if scale != [1, 1, 1] and scale != (1, 1, 1): + name = a.get("actor_name", "") + asset_key = a.get("asset_key", "") + # 计算实际尺寸 + from config.asset_mapping import MESH_ASSETS + default_size = MESH_ASSETS.get(asset_key, {}).get("default_size", (100, 100, 100)) + if default_size: + actual = ( + f"{default_size[0]*scale[0]:.0f}×" + f"{default_size[1]*scale[1]:.0f}×" + f"{default_size[2]*scale[2]:.0f}" + ) + else: + actual = "(默认尺寸未知)" + lines.append(f"| {name} | {asset_key} | ({scale[0]:.2f},{scale[1]:.2f},{scale[2]:.2f}) | {actual} |") + + lines.append("") + + report = "\n".join(lines) + + # 写入文件 + if output_path: + Path(output_path).write_text(report, encoding="utf-8") + print(f"报告已写入: {output_path}") + + return report diff --git a/tools/level-builder/validation/__init__.py b/tools/level-builder/validation/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tools/level-builder/validation/asset_validator.py b/tools/level-builder/validation/asset_validator.py new file mode 100644 index 0000000..9eb7764 --- /dev/null +++ b/tools/level-builder/validation/asset_validator.py @@ -0,0 +1,103 @@ +"""离线资产验证模块。 + +检查解析数据中的资产引用是否有效: + 1. asset_key 是否在 asset_mapping 中定义 + 2. 材质名是否在 material_mapping 中定义 + 3. Content/ 目录下 .uasset 文件是否存在(可选) +""" + +import logging +from pathlib import Path +from dataclasses import dataclass + +from config.asset_mapping import MESH_ASSETS +from config.material_mapping import MATERIAL_PATHS + +logger = logging.getLogger("level_builder.validator") + + +@dataclass +class ValidationResult: + """验证结果。""" + total_actors: int = 0 + valid_actors: int = 0 + warnings: list[str] = None + errors: list[str] = None + missing_assets: set[str] = None + missing_materials: set[str] = None + + def __post_init__(self): + if self.warnings is None: + self.warnings = [] + if self.errors is None: + self.errors = [] + if self.missing_assets is None: + self.missing_assets = set() + if self.missing_materials is None: + self.missing_materials = set() + + @property + def is_valid(self) -> bool: + return len(self.errors) == 0 + + +def validate_actors(actors: list[dict], project_root: str = "") -> ValidationResult: + """验证 Actor 列表中的资产引用。 + + Args: + actors: Actor 数据列表(来自解析器的 JSON 输出)。 + project_root: 项目根目录路径(用于文件存在性检查)。 + + Returns: + ValidationResult 包含所有验证信息。 + """ + result = ValidationResult(total_actors=len(actors)) + + for i, actor in enumerate(actors): + name = actor.get("actor_name", f"") + asset_key = actor.get("asset_key", "") + material = actor.get("material", "") + asset_type = actor.get("asset_type", "static_mesh") + + # 跳过非 mesh 类型(光照、PlayerStart 等) + if asset_type != "static_mesh": + result.valid_actors += 1 + continue + + # 检查 asset_key + if not asset_key: + result.warnings.append(f"{name}: 无 asset_key(可能是光照/特殊 Actor)") + result.valid_actors += 1 + continue + + if asset_key not in MESH_ASSETS: + result.errors.append(f"{name}: 未知资产 '{asset_key}'") + result.missing_assets.add(asset_key) + continue + + # 检查材质 + if material and material not in MATERIAL_PATHS: + result.warnings.append(f"{name}: 未知材质 '{material}'") + result.missing_materials.add(material) + + # 检查 .uasset 文件存在性(如果提供了项目根目录) + if project_root: + mesh_info = MESH_ASSETS[asset_key] + asset_path = mesh_info["path"] + # /Game/BlockingStarterPack/Meshes/.../SM_Xxx.SM_Xxx → Content/BlockingStarterPack/Meshes/.../SM_Xxx.uasset + fs_path = asset_path.replace("/Game/", "Content/").split(".")[0] + ".uasset" + full_path = Path(project_root) / fs_path + if not full_path.exists(): + result.warnings.append(f"{name}: 资产文件不存在 '{fs_path}'") + + result.valid_actors += 1 + + # 汇总日志 + if result.missing_assets: + logger.error(f"缺失资产定义: {sorted(result.missing_assets)}") + if result.missing_materials: + logger.warning(f"缺失材质定义: {sorted(result.missing_materials)}") + logger.info(f"验证完成: {result.valid_actors}/{result.total_actors} 有效, " + f"{len(result.errors)} 错误, {len(result.warnings)} 警告") + + return result