123 lines
11 KiB
Markdown
123 lines
11 KiB
Markdown
|
|
# FR 신규 맵 5종 — 실행 순서(PM 용)
|
||
|
|
|
||
|
|
작성 2026-09-28 · 스테이징 `C:\BurningTimes\FR_maps_staging\`
|
||
|
|
|
||
|
|
> **이 빌더는 Unity 에서 한 번도 실행해 보지 않았다.** 확인한 것은 ① 컴파일 오류 0(Unity 에 든 컴파일러) ② 맵 정의의 동선 검사(파이썬) ③ 프리팹 · 텍스처 경로 존재뿐이다.
|
||
|
|
> 첫 실행은 맵 하나(Graveyard)로 하고, 로그와 화면을 본 뒤 나머지를 돌리는 것을 권한다.
|
||
|
|
|
||
|
|
## ① 복사할 파일
|
||
|
|
|
||
|
|
스테이징의 `Assets\` 아래를 프로젝트의 같은 경로로 복사한다(`.meta` 는 없다 — Unity 가 만든다). 기존 파일을 덮어쓰는 것은 없다(전부 새 경로).
|
||
|
|
|
||
|
|
| 스테이징 경로 | 내용 | 개수 |
|
||
|
|
|---|---|---:|
|
||
|
|
| `Assets\BurningTimes\Editor\Maps\*.cs` | 공용 빌더(네임스페이스 `BurningTimes.EditorTools.Maps`) | 10 |
|
||
|
|
| `Assets\BurningTimes\Maps\<이름>\<이름>.map.json` | 맵 정의(데이터) | 5 |
|
||
|
|
| `Assets\BurningTimes\Maps\<이름>\Textures\FRMap_*.png` | 새로 만든 바닥 · 액체 텍스처(1024, 노멀 포함) | 20 |
|
||
|
|
|
||
|
|
```
|
||
|
|
robocopy C:\BurningTimes\FR_maps_staging\Assets C:\BurningTimes\FirstRising\Assets /E
|
||
|
|
```
|
||
|
|
|
||
|
|
빌더 파일 10개: `MapBuilder`(메뉴 · 진입점) · `MapDef`(데이터) · `MapContext`(실행 상태) · `MapGeometry`(거리 · 보이는 범위) · `MapPropPlacer`(소품 놓기 · 충돌 판정) · `MapTerrainBuilder`(바닥) · `MapLiquidBuilder`(물 · 용암 · 독액) · `MapDresser`(장면 묶음 · 담 · 띠) · `MapWalkMask`(걸을 수 있는 마스크 · 보이지 않는 벽) · `MapSceneAssembler`(씬 · 분위기).
|
||
|
|
숲 맵 빌더(`TV2DiabloMap.cs`)와 숲 맵 씬 · 에셋은 건드리지 않는다.
|
||
|
|
|
||
|
|
## ② 실행 명령
|
||
|
|
|
||
|
|
전제: **Play 중이 아닐 것 · 컴파일 중이 아닐 것 · 이름 없는(저장 안 한) 씬이 열려 있지 않을 것.** 지금 열려 있는 씬은 닫지 않는다(빌더가 새 씬을 덧붙여 열었다가 끝나면 닫고, 활성 씬을 되돌린다).
|
||
|
|
|
||
|
|
| 순서 | 명령 | 비고 |
|
||
|
|
|---|---|---|
|
||
|
|
| 1 | `unity command eval_file --file C:\BurningTimes\FR_maps_staging\unity_eval\map_refresh.cs --json` | 복사한 파일 가져오기 + 컴파일(이 프로젝트는 Auto Refresh 가 꺼져 있다). **Play 중이면 하지 말 것** |
|
||
|
|
| 2 | `unity command recompile_status` → 끝난 뒤 `unity command get_console_logs --severity error` | 컴파일 오류 0 확인 |
|
||
|
|
| 3 | `unity command eval_file --file ...\unity_eval\map_probe.cs --json` | 준비물 확인(아무것도 바꾸지 않는다). `builder=True` · 맵마다 `json=True tex=n/n` |
|
||
|
|
| 4 | `unity command eval_file --file ...\unity_eval\map_build_Graveyard.cs --detach` | 맵 하나 짓기. 끝나면 `Logs/bt_map_graveyard.txt` 마지막 줄이 `RESULT: OK` |
|
||
|
|
| 5 | 나머지: `map_build_RuinedKeep.cs` · `map_build_SpiderCave.cs` · `map_build_PlagueCatacomb.cs` · `map_build_HarborExecution.cs` (한꺼번에는 `map_build_all.cs`) | 모두 `--detach` |
|
||
|
|
| 6 | `Assets/Scenes/Maps/<이름>.unity` 를 열고 Play | 처음 열 때 맵 서브씬을 굽는다 |
|
||
|
|
|
||
|
|
- 코드에서 부를 때: `BurningTimes.EditorTools.Maps.MapBuilder.Build("Graveyard")` — 이름은 `Graveyard` · `RuinedKeep` · `SpiderCave` · `PlagueCatacomb` · `HarborExecution`. 로그 문자열을 돌려준다.
|
||
|
|
- 메뉴: `BurningTimes/Maps/<맵 이름>/Build` · `Remove` · `BurningTimes/Maps/모두 Build (5종)`.
|
||
|
|
- 걷어내기: `map_remove_<이름>.cs` 또는 메뉴 Remove — 빌더가 놓은 루트(`Map_<이름>` · `Map_<이름>_Ground` · `Map_<이름>_Bounds` · `Map_<이름>_Moon` · `Map_<이름>_Lights`)만 지운다. 씬 · 에셋 파일은 남는다.
|
||
|
|
- 다시 짓기: Build 를 다시 부르면 위 루트를 지우고 같은 시드로 다시 짓는다(결과 동일).
|
||
|
|
|
||
|
|
### 빌더가 만드는 것
|
||
|
|
|
||
|
|
| 경로 | 내용 |
|
||
|
|
|---|---|
|
||
|
|
| `Assets/Scenes/Maps/<이름>.unity` | 메인 씬 — `Assets/Scenes/TestVisual.unity` 사본(LevelEssential · TestMonstersController · SubScene · BT_Visual 유지). 이미 있으면 다시 복사하지 않는다 |
|
||
|
|
| `Assets/Scenes/Maps/<이름>/<이름>_Map.unity` | 맵 서브씬 — 빈 씬에서 새로 만든다 |
|
||
|
|
| `Assets/BurningTimes/Maps/<이름>/Terrain/` | 지형 데이터 · 지형 층 4개 |
|
||
|
|
| `Assets/BurningTimes/Maps/<이름>/Meshes/` | 보이지 않는 벽 메시 · 액체 수면 메시 |
|
||
|
|
| `Assets/BurningTimes/Maps/<이름>/Materials/` | 액체 재질 · 가림 반투명 재질(`Fade/`) |
|
||
|
|
| `Assets/BurningTimes/Maps/<이름>/Settings/<이름>_Volume.asset` | 후처리 볼륨 사본(맵마다 색 보정) |
|
||
|
|
| `Logs/bt_map_<이름>.txt` · `_layout.json` · `_props.json` · `_walkable.png` | 결과 기록(이름은 소문자) |
|
||
|
|
|
||
|
|
전역 저장(`AssetDatabase.SaveAssets`)은 쓰지 않는다. 우리가 만든 에셋만 `SaveAssetIfDirty` 로 저장하고, 씬은 위 두 개만 저장한다.
|
||
|
|
|
||
|
|
## ③ 예상 소요
|
||
|
|
|
||
|
|
**미확인(실측 없음).** 어림: 맵당 30~120초(지형 칠 512² · 소품 500~1,100개 놓기 · 담 따라가기). `unity command` 의 5초 제한을 넘으므로 반드시 `--detach`.
|
||
|
|
처음 Play 할 때 서브씬 굽기는 숲 맵 기준 20~30초 이상.
|
||
|
|
|
||
|
|
## ④ 실행 뒤 확인할 것
|
||
|
|
|
||
|
|
### 로그 `Logs/bt_map_<이름>.txt`
|
||
|
|
|
||
|
|
| 줄 | 기대값 | 어긋나면 |
|
||
|
|
|---|---|---|
|
||
|
|
| `RESULT:` | `OK` | `FAIL` 이면 그 뒤 예외 내용을 본다 |
|
||
|
|
| `이어지지 않는 조각` | **0 ㎡** | 0 이 아니면 어딘가 끊겼다 — 마스크 PNG 로 위치 확인 |
|
||
|
|
| `연결 복구: … 를 열었다` | 이 줄이 **없어야** 한다 | 있으면 그 공터로 가는 길을 소품이 막았다는 뜻(소품 배치 조정 필요) |
|
||
|
|
| `길 폭(중심선 기준 가장 좁은 곳)` | `6 m 미만 없음` | 몰이사냥 병목 기준 위반 — 그 길 가장자리 소품 확인 |
|
||
|
|
| `보스전 자리 안 … 막힌 칸` | **0 ㎡** | 보스 공터 안에 소품이 들어갔다 |
|
||
|
|
| `몬스터 무리 자리 … 확인 필요` | `없음` | 그 무리 자리가 막혔거나 둘레가 좁다 |
|
||
|
|
| `없는 프리팹 · 풀` | `없음` | 경로가 바뀌었다 |
|
||
|
|
| `점광원` | 48 이하 | 상한을 넘어 빛을 달지 않은 장치 수가 많으면 상한(`lightBudget`)이나 묶음의 빛을 조정 |
|
||
|
|
| `옛 셰이더(LOD 하위) 재질 교체 렌더러` | 참고 | 분홍색 소품이 보이면 이 수와 함께 보고 |
|
||
|
|
| `길 한가운데 · 공터 가운데라 놓지 않은 막는 소품` | 참고 | 많으면 묶음 자리가 길과 겹친다 |
|
||
|
|
| `담 '…'` | 먼 쪽 · 카메라 쪽 개수 | 0 이면 담이 안 놓였다 |
|
||
|
|
|
||
|
|
### 그림
|
||
|
|
|
||
|
|
- `Logs/bt_map_<이름>_walkable.png`(흰색 = 이동 가능 · 0.5 m 격자 · 위 = -z)을 `docs/img/<이름>_walkable_design.png`(소품 전 설계값)과 견준다. 길 · 공터의 큰 꼴이 같아야 하고, 소품 자리만 파여야 한다.
|
||
|
|
- 탑뷰 동선도 `docs/img/<이름>_topview.png` 와 실제 화면의 랜드마크 위치.
|
||
|
|
|
||
|
|
### 화면(Play · 캡처 권장 지점)
|
||
|
|
|
||
|
|
1. 시작 위치 — 야영지가 길을 막지 않는가 · 분위기 색이 테마대로인가.
|
||
|
|
2. 모아서 잡는 자리 — 가운데가 트였는가 · 키 큰 소품이 캐릭터를 가리지 않는가.
|
||
|
|
3. 보스전 자리 — 문 폭 · 둘레 담이 끊김 없이 이어지는가 · 바닥 띠가 읽히는가.
|
||
|
|
4. 담 — 조각이 겹치거나 비지 않는가 · 방향이 경계를 따라가는가.
|
||
|
|
5. 액체 — 수면 높이 · 색 · 발광 세기(용암 · 독액) · 물가가 지형에 자연스럽게 묻히는가.
|
||
|
|
6. 소품 크기 — 사람 키(약 1.8 m) 대비 어색한 것.
|
||
|
|
7. 충돌 — 보이는 것이 막고 비어 보이는 곳이 통과되는가(숲 맵과 같은 기준으로 자동 주행 `TVAutoPilot` · 배치 좌표는 `_layout.json`).
|
||
|
|
8. 몰이 — 무리를 끌고 고리를 돌 때 몬스터가 걸리는 곳.
|
||
|
|
|
||
|
|
## ⑤ 알려진 위험 · 미확인
|
||
|
|
|
||
|
|
| # | 내용 | 영향 | 대응 |
|
||
|
|
|---|---|---|---|
|
||
|
|
| 1 | **Unity 에서 실행한 적 없음** | 실행 중 예외 · 기대와 다른 배치 | 맵 하나로 먼저 실행 · 로그 확인. 예외가 나도 연 씬은 저장 없이 닫힌다 |
|
||
|
|
| 2 | 메인 씬은 `TestVisual.unity` **디스크 저장본**을 복사한다 | 보스 작업 구성(TVBossDirector 등)이 그대로 따라온다. 저장하지 않은 변경은 빠진다 | 뜻한 바가 아니면 복사 전에 TestVisual 을 저장하거나, 만든 메인 씬에서 정리 |
|
||
|
|
| 3 | 이름 없는 씬이 열려 있으면 새 씬을 덧붙여 만들 수 없다(Unity 제약) | 첫 Build 실패 | `map_probe.cs` 의 `untitledSceneOpen` 확인 |
|
||
|
|
| 4 | 프리팹 크기 · 방향은 놓을 때 재서 맞춘다 | 보이지 않는 조각(입자 · 그림자용 메시)이 크기에 섞이면 배율이 틀어질 수 있다 | `_props.json` 의 `scale` · 크기로 확인 → JSON 의 `fit`/`a`/`b` 조정 |
|
||
|
|
| 5 | MEP · MEP1 프리팹의 높이 축 미확정 | 목표 높이(`fit h`)로 적은 동굴 벽 · 석순 · 수정 · 버섯은 빌더가 실측하므로 영향 없음. 배율(`fit s`)로 적은 것은 숲 맵에서 쓴 값 | — |
|
||
|
|
| 6 | 불꽃 색 바꾸기(녹색 · 보라)는 입자 시작 색에 곱하는 방식 | 재질에 따라 색이 안 바뀔 수 있다 | 화면 확인 |
|
||
|
|
| 7 | 담은 경계선을 따라가며 한 칸씩 놓는다 | 굽은 곳 · 좁은 곳에서 겹치거나 빌 수 있다 | `seg`(한 칸 길이) · `gap` 조정 |
|
||
|
|
| 8 | 낭떠러지(`void`)는 지형만 파낸다(수면 없음) | 바닥 텍스처가 보여 구덩이처럼 보일 수 있다 | 어두운 판 · 안개 추가 검토 |
|
||
|
|
| 9 | 몬스터가 보이지 않는 벽 · 소품을 피하는 방식 미확인 | 몰이 중 걸림 | Play 실측 |
|
||
|
|
| 10 | 몬스터 구역의 몬스터 번호는 본뜬 씬(TestVisual) 값을 물려받는다 | 테마와 다른 몬스터가 나온다 | 구역별 몬스터 지정은 기획 · PM 결정 |
|
||
|
|
| 11 | 게임 본편 맵 목록(MapTable) 등록 없음 | 에디터 테스트 씬으로만 실행된다 | 본편 반영은 PD 지시 시 |
|
||
|
|
| 12 | 모바일 성능 미확인(소품 수 · 점광원 48 · 지형 1장) | — | 에디터 실측(배치 수 · 삼각형) 후 밀도(`density`) 조정 |
|
||
|
|
| 13 | 새 텍스처는 기본 압축(고품질)만 맞춘다(안드로이드 · iOS 개별 설정 없음) | 기기 빌드에서 형식이 기본값 | 필요 시 ASTC 지정 |
|
||
|
|
| 14 | 단두대 · 교수대 · 거미 알 모델 없음 | 처형대 · 알 둥지가 대체 소품 | 에셋조사 §6 — PD 결정 |
|
||
|
|
| 15 | 커밋 없음 | 새 파일은 모두 미추적 상태로 남는다 | PD 지시 시 커밋 |
|
||
|
|
|
||
|
|
## 값 고치기(재컴파일 없이)
|
||
|
|
|
||
|
|
맵 정의는 JSON 이라 값을 고친 뒤 Build 만 다시 부르면 된다.
|
||
|
|
|
||
|
|
- 직접 고치기: `Assets/BurningTimes/Maps/<이름>/<이름>.map.json`
|
||
|
|
- 원본에서 다시 만들기(권장 — 동선 검사 · 동선도가 함께 갱신된다): `tools/maps_def.py` 를 고치고 `python tools/build_maps.py` → `python tools/estimate_props.py` → `python tools/make_docs.py` → JSON 을 프로젝트로 복사.
|
||
|
|
- 컴파일 확인(에디터 없이): `bash tools/csc_check_maps.sh` — 프로젝트에는 아무것도 쓰지 않는다.
|