ThreeKingdomsSlingshot/CLAUDE.md

120 lines
46 KiB
Markdown
Raw Permalink Normal View History

# 삼국지 슬링샷 (가제) — 에이전트 작업 지침
> 너드나비스 조직 프로젝트 ⑤ (조직 레포 `.claude/skills/너드나비스-코어룰/rules/P38.md` §P38-3 ⑤). 새 세션은 조직 레포 `공유/인계서/삼국지슬링샷_인계서.md` → 이 파일 → `README.md` 순서로만 읽고 시작한다. 조직 규칙 본문 전수 읽기 금지(C10-1).
## 프로젝트 정보
- Unity **6000.3.23f1** · 2D · 빌트인 RP · 레거시 Input(`activeInputHandler: 0`) · Portrait · 패키지 = 기본 모듈 + `com.unity.ugui 2.0.0` + `com.unity.test-framework 1.6.0` + `com.unity.pipeline 0.10.0-exp.1`(2026-11-04 P38-7 적용).
- git = 이 폴더가 레포 루트 · `main` · 원격 `origin` = `https://burning.i234.me/NerdNavis_AiDev/ThreeKingdomsSlingshot.git`(비공개 · 2026-11-09 · 다른 PC 와 함께 작업 = 시작 전 `git pull` · 커밋 후 `git push`). 미추적 = `Library/` `Temp/` `Logs/` `UserSettings/` `obj/`(Unity 표준 `.gitignore` · Pipeline 포트 파일 `Library/Pipeline/.unity-pipeline-port` 도 그 안).
- 기록 = 조직 레포 `공유/대화로그/삼국지슬링샷/` · 인계서 `공유/인계서/삼국지슬링샷_인계서.md` · PD 지시 로그 #1077.
## 에디터 제어 = Unity 공식 CLI + `com.unity.pipeline` (P38-7)
기본 호출은 MCP 가 아니라 **셸에서 `unity …` 직접 호출**이다(Unity 공식 권장 · 토큰 적음). `unity` 명령은 PowerShell 로 호출하되, C# 코드에 큰따옴표가 들어가는 `eval` 류는 Bash 도구로(K-DEV-026). 에디터가 둘 이상 열려 있으면 `--project-path E:\Nerdnavis\ThreeKingdomsSlingshot` 또는 환경 변수 `UNITY_PROJECT_PATH` 로 대상을 지정한다(K-DEV-024).
### 에디터가 열려 있을 때 (PD 플레이 중 반복 수정)
```
unity status --project-path . # ready 확인(포트·PID)
unity recompile --project-path . # 수정 후 재컴파일 · 컴파일 오류 0 이어야 통과
unity command --project-path . # 등록된 명령 목록(콘솔 읽기 · 메뉴 실행 등)
unity command --project-path . <명령> [인자] # 명령 실행 · --result-only 로 JSON 만
unity command --project-path . test run --mode playmode --async-tests --timeout 600 --result-only # 열린 에디터 안에서 테스트 시작(비동기 필수 · Play 진입의 도메인 리로드가 동기 요청을 끊음)
unity command --project-path . test status --result-only # 끝날 때까지 10초마다 폴링 · test list / cancel 도 있음
# ※ `unity test <proj> --mode PlayMode` 는 자체 배치 인스턴스를 띄우므로 에디터가 열려 있으면 거부된다(2026-11-04 실측 「이미 열려 있습니다」)
unity close . [--force] # 에디터 종료(저장 없이 종료 · PD 가 연 에디터는 닫지 않는다)
```
- **작업 전에 `unity command --project-path . editor status --result-only` 로 `playMode` 를 본다.** **PD 가 Play 중(`playing`·`paused`)이어도 기다리지 말고 `unity command --project-path . editor.playmode stop` 으로 Play 를 중단 → `stopped` 확인 → 바로 작업**한다(PD 지시 2026-11-04 · 2026-11-09 재확인 「내 PC 가 플레이 중이더라도 중단하고 작업해」 · 에디터 자체는 닫지 않음). 수정을 **모두** 끝낸 뒤 리컴파일 1회(편집 중 자동 새로고침으로 잠깐 컴파일 오류가 보일 수 있음). 열린 에디터가 있으면 배치 실행은 `Temp/UnityLockfile` 로 막히고, PD 가 연 에디터는 닫지 않는다 → 검증이 급하면 `Assets`·`Packages`·`ProjectSettings` 만 복사한 사본 폴더(예 `E:\Nerdnavis\_tks_verify`)에서 배치 실행(2026-11-04 실측 · 새 Library 임포트 포함 수 분).
- 수치 자산에 새 필드를 넣었으면(예 `art` · `archerRangeRatio`) 기존 `BalanceConfig.asset` 에는 비어 있다 → 자산이 git 에서 미수정이면 메뉴 `TKS/Reset Balance Defaults`(= `BuildFresh`)로 재시드 · PD 가 Inspector 로 손본 흔적(git diff)이 있으면 재시드 금지 · 필드만 보충.
- 판정 = 컴파일 오류 0 + 콘솔 error 0(Unity 자체 `SearchDatabase` 인덱싱 예외는 무해).
### 에디터가 닫혀 있을 때 (배치 · 재현 가능한 실측)
```
Unity.exe -batchmode -nographics -projectPath <proj> -executeMethod TKS.EditorTools.ProjectSetup.Build -quit -logFile <log> # 컴파일 + 설정 자산·씬 생성(BuildFresh = 기본값 재시드)
Unity.exe -batchmode -nographics -projectPath <proj> -runTests -testPlatform PlayMode -testResults <xml> -logFile <log> # 플레이모드 테스트(현재 17종)
Unity.exe -projectPath <proj> -executeMethod TKS.EditorTools.ProjectSetup.AutoPlayCapture -autoplayDir <dir> -autoplayTurns 3 # GUI 자동 플레이 캡처 · 스스로 종료
```
- `Unity.exe` = `C:\Program Files\Unity\Hub\Editor\6000.3.23f1\Editor\Unity.exe`. 에디터가 같은 프로젝트를 열고 있으면 배치 실행은 못 한다(`Temp/UnityLockfile`) — 먼저 `unity status` 로 확인.
- 배치 로그 판정 = `error CS` 0 · 테스트 XML `failed="0"`.
- **에디터가 열리면서 크래시하면 oCam(화면 녹화)을 의심**: `%LOCALAPPDATA%\Unity\Editor\Editor.log` 꼬리의 스택에 `HookSurfaceDLL` → `D3D12SwapChain::Present` 가 있으면 oCam 의 D3D12 훅이 원인(2026-11-04 15:04 × 2 실측). 이 프로젝트는 그래서 Windows Graphics API 를 **D3D11 우선**으로 고정했다(`ProjectSettings.asset` `m_BuildTargetGraphicsAPIs` · 에디터도 이 설정을 따름). 그래도 크래시하면 `-force-d3d11` 인수 또는 oCam 종료. 배치 `-nographics` 는 영향 없음.
## 코드 규칙
- 전투 수치 SOT = `Assets/Resources/BalanceConfig.asset`(Inspector 조정 · 최초 시드만 `Assets/Scripts/Editor/BalanceDefaults.cs`). 코드·테스트에 수치를 직접 적지 않는다(C45).
- **아웃게임 SOT = `Assets/Data/OutGame/*.csv`(12장 · 기획 `공유/기획팀_산출물/삼국지슬링샷/tables/` 사본 · utf-8-sig · 2026-11-05 #1093 A)** — 영웅·병사(`heroes.csv` · 구 `BalanceConfig.heroes[]` 대체) · 레벨·승급·진화·장비·뽑기·보상·재화·신규 유저 초기값(`economy.csv` start_*). 고친 뒤 메뉴 `TKS/Import OutGame Data (아웃게임 데이터 임포트)`(`Editor/DataImporter` · 오류 시 자산 불변) → `Resources/OutGame/` 9 자산. 표를 바꾸면 기획 `tables/` 도 같이.
- **스킬(2026-11-10 #1112 전면 개편 · PD 엑셀 「장수 목록」 새 기획 144개)** — 수치 SOT = **`Assets/Data/OutGame/skill_effects.csv`(효과 1줄 = `skill_id · key · target · cond · dur · p1~p3` + 한글 주석 열 `effect_ko · p1_ko~p3_ko` = 밸런싱용 · 게임은 안 읽음)** · `skills.csv` = 이름·발동(next_action|instant|always)·쿨·설명 · `effect_key` = 효과 키 목록(p 칸 비움) · `heroes.csv gender`(m|f = 남성·여성 조건). 원본 = 기획 `tables/`(생성기 `_tables_t1.py` SKILL_EFFECTS · KEY_DOC 주석 사전 · 이름·설명 = `영웅_리스트_스킬.md` · 실행 뒤 `economy.csv`·`gacha.csv` 는 git 되돌림 = 생성기보다 손으로 늘린 판이 최신). 처리기 = `Runtime/Skills/`: `SkillKeys`(121종 · 레벨 계수 칸) · `SkillMods`(대상 칸 자신/allies/camp/radius/range/aura · 조건 칸 crit/vs_*/turn_le/armed · 공격·피해·치명타·반격·슬링 질의) · `SkillSystem`(쿨·예약 · 시한 효과 = 라운드(주인 진영 턴 시작마다 −1) · 피해 적용 `Hit(d, dmg, by, HitKind)` = 무적→무효화→호위→부활→흡혈·명중 상태 이상→처치 보상 · 재행동 `ReactCredits` · 즉시형 · `TurnBegin(side)` = 상대 턴 끝 회복·정화 + 중독·화상·회복·지대 · 행동 중 탭 `WaitTap`(조조·하후돈 · 테스트 `AutoTap`) · 지대 `SkillZone`) · `SkillStatus`(혼란·출혈·중독·화상 · 기절 = 기믹 `GimmickLayer.Stun` 재사용) · 특수 이동 = `ActionResolver`(관통·핀볼·복귀·교환·끌어오기·난동·반복) · 특수 사격 = `ActionResolver.Skills.cs`. 가상 실행 = `SkillSystem.TakeState/RestoreState`(Sim). PD 결정 18건(2026-11-10 · 대화로그 `2026-11-10_스킬구현.md`): 「1 m」 = 전장 1 칸 · 「행동 반경」 = 기본 슬링 거리 · 기획에 없는 지속 턴 = 1 · 출혈 = 슬링 최대 거리 이동 시 최대 HP 50 % · 망령 = 다음 자기 턴 시작에 1번 공격 후 소멸 · 육손 불 장벽 = 아군도 · 손건 화친 = 피해 없이 회복만 · 보병 목표점 추가 이동 제거. 테스트 = `Tests/PlayMode/SkillTests`(효과 묶음 26 · PD 결정·Fable 검토 반영 포함). 캡처 = `-executeMethod TKS.EditorTools.DataImporter.CaptureSkills -skillDir <dir>`.
아웃게임 2차(PD #1093 세션 C) — 내정(훈련·순찰·개발) · 보물(수집품·세트·상자) · 연무장(탑·일일 던전·투기장·적장 토벌) · 거래 상자 탭 + 영웅 56명 확장(PD #1096 · 신규 effect_key 4) - 데이터: C 표 10장(training · training_ranks · patrol · dev_tree · treasures · treasure_sets · chests(+iron/buy 열) · tower · dungeons(+reward_amount) · arena(+상점 키)) + economy.csv C 키 24 → 임포트 18 자산(OutGameTables.C.cs 검증: 행·연속 Lv/랭크/층·참조·확률 합 1·선행 노드·효과 키 처리기·카운터 키 · 오류 시 자산 불변) - 영웅 56명: heroes 71 · skills 112 · hero_gear 1344 · gacha_pool 71 재복사 · 신규 키 4(team_dmg_pct_turn · cooldown_add · charm · heal_self_pct) + 기존 키 조건 열(받는 피해 p2 HP 임계/보스/근접 · p3 출전 인원 아군 전원 · 최대 HP·반격 아군 전원 · 피해 % 발동 턴) · 대장군 키는 표 미사용(처리기 유지) - 내정: 훈련(병종 5 · 3항목 Lv · cost_mult · 랭크 승급 · train_bonus → §3-2 항목별) · 순찰(챕터 행 × 시간 · 오프라인 · 상한 12h + 농업 · 소수점 이월 · 광고 2배 스텁 · 즉시 수확 보옥) · 개발(갈래 3 · 선행 · 골드·도면 비용 · 효과 키 → 군량·보상·상점·순찰·상자 적용 지점 · 초기화 보옥 + 도면 환급) - 보물: 보유 중(4열 · 등급 색 · 상세·강화) · 세트(단계 효과) · 상자(포인트 → 명장 · 확률 · 중복 조각) · 효과 hp/atk/def → HeroRules · crit/range/splash → BattleManager.SideEffectsProvider → SkillMods · 조건 카운터 8종 = Runtime/BattleEvents(전투 코드 Raise 1줄씩 · 아군만) · 스테이지 청동 상자 10 % - 연무장: BattleManager.StartMode(BattleMode = 적 편성·제한 턴·onExit) · 탑 100층(입장권·층 배율·보상·10층 상자) · 던전 3(요일·2/일·보상) · 투기장(샘플 10 · EnemyAI 방어 · 메달·주간 순위·조각 상점) · 적장 토벌(주간 순환·hp ×20·5턴·누적 피해·명장 상자·천기) · 결과 패널 → 탭 = 연무장 - 거래: 상자 탭(구매 = 골드/보옥/포인트 · 거래 할인) · 패스·월정액·챕터 팩·첫 결제 팩 = 준비 중 스텁 · 스킬서 임시 판매 제거(사당 던전) - 테스트 87/87(기존 73 유지 · 갱신 3 = 로비 탭 · 표 키 목록 · 상점 스킬서 칸 / 신규 14 = OutGameCTests 12 + 확장 키 2) · console error 0 · 캡처 = DataImporter.CaptureC Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 15:22:54 +00:00
- **아웃게임 2차(2026-11-05~06 #1093 C)** — 표 10장 추가(`training` · `training_ranks` · `patrol` · `dev_tree` · `treasures` · `treasure_sets` · `chests`(+ iron/buy 열) · `tower` · `dungeons`(+ reward_amount) · `arena`(+ 상점 키)) + `economy.csv` C 키 24 → 임포트 자산 18(A 9 + C 9 · `OutGameTables.C.cs` 검증). 코드 = `OutGame/Domestic/`(`TrainingRules` 훈련 · `PatrolRules` 순찰 · `DevRules` 개발 효과 키 → 적용 지점 · `DomesticScreen`) · `OutGame/Treasure/`(`TreasureRules` 보유·세트·강화·조건 카운터·상자 · `TreasureScreen`) · `OutGame/Arena/`(`ArenaRules` 탑·던전·투기장·적장 · `ArenaScreen`). 스탯 = §3-2 × (1 + 훈련(병종·항목)) × (1 + 보물(항목)) = `HeroRules.Compute(…, save)` · 보물 crit/range/splash = `BattleManager.SideEffectsProvider` → `SkillMods.Get` 진영 효과(`side_crit_pct` · `range_mult` · `splash_radius_mult`) · 조건 효과 카운터 = `Runtime/BattleEvents.Raise`(전투 코드 1줄씩 · 아군만) · 연무장 전투 = `BattleManager.StartMode(BattleMode)`(적 편성 · 제한 턴 · 결과 탭 = `onExit`) → `OutGameSession.OnModeEnd`. 테스트 = `Tests/PlayMode/OutGameCTests`. 캡처 = `-executeMethod TKS.EditorTools.DataImporter.CaptureC -cDir <dir>`(사본 · 10장).
장수 스킬 144개 새 기획 구현(#1112 · PD 2026-11-10 엑셀 「장수 목록」) — 효과 표 skill_effects.csv(효과 1줄 · 한글 주석 열) · 이름 56개 새로 - 수치 SOT = Assets/Data/OutGame/skill_effects.csv(skill_id·key·target·cond·dur·p1~p3 + effect_ko·p1_ko~p3_ko 주석) · skills.csv effect_key = 키 목록 · heroes.csv gender(m|f) - 처리기 121종(SkillKeys) · 대상 칸(자신·같은 편·진영·반경·행동 반경) · 조건 칸(치명타·상대 상태 이상·병종·성별·턴·장착 중) · 지속 라운드 - 상태 이상 = 혼란·출혈(이동 거리 비례)·중독(중첩)·화상 + 기절(기믹 행동 불가 재사용) · 정화 · 회복·흡혈·부활·무적·무효화·호위(반격) - 재행동(유비·위연·여몽·손견·곽가·우금·맹획·감녕·고순·장합) · 치명타 확률·피해·무조건 - 이동 변형: 관통(손견·안량·손책 아군 통과) · 핀볼 튕김(손책·동탁) · 복귀(조운·손책·여포·문추·공손찬·순우경 · 하후돈 탭 지점·쓸어 감) · 위치 교환(위연) · 끌어오기(장료) · 아군 통과+탭 방향 밀치기(조조) · 반복(정보) · 난동(동탁) - 특수 사격: 거대 화살 · 직선 관통 · 폭발(화염구·독구름·운석·화살비) · 부채꼴 · 멀티샷 · 도탄 · 회오리 · 목책 · 불 장벽·불꽃·독 지대 · 궁병식 비도 · 광역 회복 - 즉시형: 광역 타격·밀기 · 흡수 · 일제 사격 · 미인계 끌어오기 · 범위 회복·정화 · 재행동 부여 · 변진 - 가상 실행(적 AI) 스킬 상태 사본(TakeState/RestoreState) · 옛 견제 스킬 확장 제거 - 테스트(고친 부분 클래스만): SkillTests 19(새로) · BattleFlowTests 42 · TacticalAITests 7 · GimmickTests 19 · OutGameTests 15 · OutGameCTests 12 전부 통과 · console error 0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 10:00:18 +00:00
- **영웅 72명(PD #1108 · 2026-11-10)** — heroes 87행(영웅 72 + 병사 15) · skills 144 · skill_effects 288 · 옛 키 체계(51+4종 · 견제·관통 배율 등)는 #1112 에서 폐기.
- **지형 기믹 레이어(PD #1097 · 2026-11-06 세션 D)** — SOT = `Assets/Data/Gimmicks/{gimmicks,stage_gimmicks,tutorial_tips}.csv`(기획 `tables/` 사본 · utf-8-sig) → 메뉴 `TKS/Import Gimmicks (기믹 임포트)`(`Editor/GimmickImporter` · 오류 시 자산 불변 · `ai_weights.csv` 도 함께) → `Resources/Gimmicks/GimmickDb`·`StageGimmickTable` · `Resources/AI/AiWeights`. 전투 시작 = `GimmickLayer.Build(stage)`(장-번호 배치 · 배경 위 · 유닛 아래 · 장애물 = 콜라이더 + `GimmickBody` · 지대 = 모양 스윕 · 강 = 늪처럼 통과하는 지대(강 안 ×p3 · 다리 구간 = 효과 없음 · 강가·다리에서 밀려 강물에 들면 빠짐 · PD 2026-11-06 개정) · 겹친 유닛은 빈 자리로). 전투 코드는 질의만: `Combat.FreeTravel`(장애물 = 벽 · 숨은 함정 정지) · `FirstUnitOnArrow`(pass/block/destroy) · `Combat.Damage`(군기 공 · 고지 근접 피격 · 안개 원거리 피격 ×p1 · 책사 광역이 그 반경 안개를 걷음) · `SkillMods.Range`(고지 사거리) · `BattleManager` 턴 시작 `TurnStart`(군기·중독·불·행동 불가). 충돌 반응·폭발·굴림·미끄러짐·지대 = `Gimmicks/ActionResolver.Gimmicks.cs`(partial). 배치 도구 = `TKS/Gimmick Painter (기믹 배치)`. 테스트 = `Tests/PlayMode/GimmickTests` · 캡처 = `-executeMethod TKS.EditorTools.GimmickImporter.Capture -gimmickDir <dir>`(사본).
지형 기믹 레이어(PD #1097 세션 D) + 병종 규칙 개정 2건 · 예측 시뮬레이션 적 AI(PD #1098) - 데이터: Assets/Data/Gimmicks/{gimmicks,stage_gimmicks,tutorial_tips}.csv + Assets/Data/AI/ai_weights.csv(기획 tables/ 사본) → 메뉴 TKS/Import Gimmicks(검증 · 오류 시 자산 불변) → Resources/Gimmicks/GimmickDb(16)·StageGimmickTable(16 + 팁 3) · Resources/AI/AiWeights(32) - 레이어: GimmickLayer(전투 시작 = 스테이지 배치 · 배경 위 유닛 아래 · 원/사각/다각 · 색 도형 + 글자 · 내구 핍 · 강 콜라이더 = 다리 구간 제외 · 겹친 유닛 보정) · 장애물 = 병종별 내구 피해·튕김·창 목책 밀기·바위 굴림·기병 정지 · 투사체 pass/block/destroy · 폭약 광역(아군 포함)+밀기+불 · 책사 광역 덤불 제거 · 강 낙하 - 지대: 경로 스윕(독 1→2→3 % · 늪 ×2 · 불 10 % · 빙판 미끄러짐 · 고지 · 안개 · 군기 · 함정) · 양 진영 턴 시작 훅 - 규칙 개정: 보병 튕김 중 다른 적과 연쇄 1회 · 창병 반작용(spearRecoilRatio · 밀며 전진 폐기) · 기존 테스트 기대값 갱신 - 적 AI: Runtime/AI(Sim 가상 실행 · TacticalAI 후보·점수·난이도·턴 운영 · 1부 보스 액티브) · 조준선 = 가상 실행 예상 궤적·기믹 반응·지대 띠 · TKS/Gimmick Painter · 캡처 GimmickImporter.Capture - 검증: 컴파일 0 · 플레이모드 113/113(신규 26) · console error 0 · 적 10기 턴 결정 62 ms Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 16:20:07 +00:00
- **병종 규칙 개정 + 예측 AI(PD #1098 · 2026-11-06)** — 보병 = 적과 싸운 뒤 튕겨나는 길의 다른 적과 연쇄 교환 1회(`ActionOutcome.Chains`) · 창병 = 상대만 밀리고 자신은 × `spearRecoilRatio` 반대로(밀며 전진 폐기). 적 턴 = `Runtime/AI/TacticalAI`(후보 방위 × 파워 3 × 액티브 → `Sim` 가상 실행(연출 없음 · 분산 0 · 상태 복원) → `ai_weights.csv` 점수 · 서포터 → 돌격 → 사격 · 1기마다 재평가) · 가중치 자산이 없으면 `EnemyAI.Decide`(기존 조준) · 적 액티브 = 1부 보스만(`boss_active`). 가상 실행 중(`Sim.Active`)에는 `Fx`·`UnitView`·`BattleEvents`·HUD 갱신이 꺼진다 — 새 연출 코드도 `Sim.Active` 면 건너뛸 것. 조준 미리보기도 같은 가상 실행(`GimmickPreview` · 숨은 함정 모름). 테스트 = `Tests/PlayMode/TacticalAITests`.
- 아웃게임 코드 = `Assets/Scripts/OutGame/**`(asmref → TKS.Runtime) — `OutGameSession`(표 + 세이브 · 바꾸는 동작은 즉시 저장) · 규칙 `HeroRules`·`EconomyRules`·`GachaRules` · 화면 `UI/`(로비·영웅·편성·거래·결과 패널 · `OutGameRoot` 가 전환). 세이브 = `persistentDataPath/save.json`(테스트·검증 캡처는 `SaveStore.UseMemory` / SessionState `TKS_SAVE_MEMORY` 로 메모리 전용). 출전 = `BattleManager.LineupProvider`(편성 프리셋 → `playerSpawnPoints` 자리 0~2 전열 · 3~4 후열). 화면 캡처 = `Unity.exe -projectPath <사본> -executeMethod TKS.EditorTools.DataImporter.CaptureOutGame -outgameDir <dir>`. **UI 수정 검증은 고친 화면만 찍는다**(PD 2026-11-09 「매번 모든 화면 체크 = 시간·토큰 낭비」): `Tools/mirror_verify.py` → `Unity.exe -projectPath E:/Nerdnavis/_tks_verify -force-d3d11 -executeMethod TKS.EditorTools.DataImporter.CaptureUI -uiDir <dir> -uiOnly hero_list,hero_detail*`(이름 = 정확히 또는 「접두*」 · 다 찍으면 바로 종료 · 1장 ≈ 15초 · 전체 21장 ≈ 3분 · 이름 목록 = `UICaptureDriver` 의 Shot 이름).
- **챕터·스테이지 SOT = `Assets/Data/Stages/*.csv`(utf-8-sig · 2026-11-05 145 스테이지 · 기획서 #1086 §4 전사)** — `stages.csv`(chapter·stage·title·type normal|elite|boss·place·faction·병종 4 수·generals `id:병종:true|false`·bg_theme·note) · `chapters.csv`(장 제목·연도·**월드맵 맵 id**·AI 출발값) · `generals.csv`(무장 id → 이름·배율 덮어쓰기) · `factions.csv`(세력 코드 → 이름·병사 아트 접두). 고친 뒤 메뉴 `TKS/Import Stages (스테이지 임포트)`(`StageImporter` · 형식 오류면 자산 미변경) → `BalanceConfig.chapters·stages`. 적 좌표 = `BalanceConfig.formation` 규칙(전위·중군·후군·장수 줄 · `StageTable.Enemies`) · 장수 배율 = `generals.csv` 가 비면 `boss/eliteGeneral*Mult`. 월드맵 노드 = 스테이지 표(챕터별 수 · 보스 = type boss) · 노드 자리 = `ChapterMap/Data/<맵>.json` `slots_N`(없으면 길 위 균등).
전투 로직 #1080 — 알까기 충돌(보병) · 관통·아군 직전 정지(기병) · 밀며 함께 전진(창병) · 밀린 아군 공격 기회 · 궁병 제자리 사격(사거리 = 슬링샷)+접근 20 % · 궁수 근접 피해 50 %/피격 +50 % · 원화 1차·2차 반영(전장 배경 + 황건적 5 + 동탁군 4) · 테스트 22/22 - ActionResolver 전면 재작성: InfantryRoutine(접촉점 정지 · Push 접촉 방향 × collisionPushRatio · 적이면 공격+반격 뒤 밀림) · SpearRoutine(앞 유닛과 같은 속도로 함께 전진 · 접촉 간격 유지) · CavalryRoutine(벽만 막음 · StopBeforeUnclearedAllies) · ArcherRoutine(AttackRange = 슬링 · ArcherMoveAllow = 슬링 × archerRangeRatio) · PushedAllyAttack(규칙 ⑤ · ActionOutcome.Pushed/Notes) - Combat: Damage(melee) 궁병 근접 배율(근접 유닛 상대만) · FirstUnitOnPath · TouchingOpponent · FreeTravel ignore - BalanceConfig/Defaults: archerMeleeDealtRatio 0.5 · archerMeleeTakenRatio 1.5 · collisionPushRatio 1 · boardArt battlefield_01 (자산 재시드) - Board: Resources/Board/<boardArt> 원화 배경(격자·진영 띠 생략) · UnitArtImporter Board 규칙 · GameBootstrap - Resources/Units: hgj_infantry·spear·cavalry·archer·boss_zhangjiao · dz_infantry·spear·cavalry·archer (원화 세션 납품 정지 그림 · rig_frames_export static) · Resources/Board/battlefield_01.png - BattleManager Describe 「밀어냄 · 밀린 B → 적 공격」 · BattleHUD 궁병 줄 · 테스트 22종(신규·개정 7 + 원화 확인) · CLAUDE.md · README Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-04 06:56:02 +00:00
- 규칙 해석 변경 = `Assets/Scripts/Runtime/ActionResolver.cs`(병종 4종) · `BattleManager.cs`(턴·승패·창병 대기) · `Combat.cs`(피해 공식·경로 질의). 변경 시 `Assets/Tests/PlayMode/BattleFlowTests.cs` 에 테스트 추가 후 22종 이상 전부 통과 확인.
- 콜라이더 질의 전 `Physics2D.SyncTransforms()` · 유닛 제거는 `SetActive(false)` 후 `Destroy` · 자식 렌더러가 있는 표시물은 GameObject 통째로 끈다.
전투 로직 #1080 — 알까기 충돌(보병) · 관통·아군 직전 정지(기병) · 밀며 함께 전진(창병) · 밀린 아군 공격 기회 · 궁병 제자리 사격(사거리 = 슬링샷)+접근 20 % · 궁수 근접 피해 50 %/피격 +50 % · 원화 1차·2차 반영(전장 배경 + 황건적 5 + 동탁군 4) · 테스트 22/22 - ActionResolver 전면 재작성: InfantryRoutine(접촉점 정지 · Push 접촉 방향 × collisionPushRatio · 적이면 공격+반격 뒤 밀림) · SpearRoutine(앞 유닛과 같은 속도로 함께 전진 · 접촉 간격 유지) · CavalryRoutine(벽만 막음 · StopBeforeUnclearedAllies) · ArcherRoutine(AttackRange = 슬링 · ArcherMoveAllow = 슬링 × archerRangeRatio) · PushedAllyAttack(규칙 ⑤ · ActionOutcome.Pushed/Notes) - Combat: Damage(melee) 궁병 근접 배율(근접 유닛 상대만) · FirstUnitOnPath · TouchingOpponent · FreeTravel ignore - BalanceConfig/Defaults: archerMeleeDealtRatio 0.5 · archerMeleeTakenRatio 1.5 · collisionPushRatio 1 · boardArt battlefield_01 (자산 재시드) - Board: Resources/Board/<boardArt> 원화 배경(격자·진영 띠 생략) · UnitArtImporter Board 규칙 · GameBootstrap - Resources/Units: hgj_infantry·spear·cavalry·archer·boss_zhangjiao · dz_infantry·spear·cavalry·archer (원화 세션 납품 정지 그림 · rig_frames_export static) · Resources/Board/battlefield_01.png - BattleManager Describe 「밀어냄 · 밀린 B → 적 공격」 · BattleHUD 궁병 줄 · 테스트 22종(신규·개정 7 + 원화 확인) · CLAUDE.md · README Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-04 06:56:02 +00:00
- **궁병 규칙(PD 2026-11-04 · #1080)**: 사거리 = `slingMaxDistance`(얇은 원). 조준 방향 사거리 안의 적(가장자리 간격 기준) = **제자리 사격** · 사거리 밖 ~ ×(1 + `archerRangeRatio`)(붉은 도넛) 안의 적 = 들어올 만큼만(최대 `ArcherMoveAllow` = 슬링 × 비율) 다가가 사격 · 더 멀면 **목표점까지 이동만**(#1079). 반격 없음 · 목표점 명중 크리. **근접 전투**(돌진·반격·관통·견제·밀려 닿은 공격)에서 궁병은 근접 유닛 상대 주는 피해 × `archerMeleeDealtRatio`(0.5) · 받는 피해 × `archerMeleeTakenRatio`(1.5) — `Combat.Damage(…, melee)` · 원거리 사격은 패널티 없음.
- **충돌 규칙(PD 2026-11-04 · #1080)** — `ActionResolver`: 보병 = 경로 첫 유닛(아군·적군)에 부딪히면 **알까기**(등속 접근 → 부딪힌 순간 피해·반격을 즉시 교환(`ImpactExchange`) → **양쪽이 동시에 튕김**: 상대는 접촉 방향으로 남은 거리 × `collisionPushRatio` · 자신은 반대 방향으로 남은 거리 × `collisionSelfBounceRatio` · PD #1081) · 기병 = 유닛 무시 관통(적 피해 · 아군은 지나칠 거리가 안 나오면 **그 아군 직전 정지** `StopBeforeUnclearedAllies`) · 창병 = 첫 유닛을 **크게 밀치고 자신은 적게 밀림**(남은 거리 × `spearPushRatio` 1.5 · 반작용 = 그 × `spearRecoilRatio` 0.2 · 적이면 피해 · 아군은 밀기만 · PD #1098 · 2026-11-10) · **규칙 ⑤** = 밀린 같은 진영 유닛이 상대와 닿으면(`Combat.TouchingOpponent` · 간격 ≤ 0.12) 그 자리에서 근접 공격 1회(조작마다 · 자기 행동 소모 없음 · `ActionOutcome.Notes`). 적 AI 도 같은 코드(대칭). `UnitStats.attackRange` = 옛 창병 견제 반경(견제 제거로 미사용).
- **사거리 표시(PD 2026-11-04)**: 유닛 탭(아군·적군) → `RangeIndicator`(슬링샷 최대 거리 = 얇은 반투명 원 · 궁병 = 슬링샷 범위 ~ ×(1+비율) 채워진 붉은 도넛 · 범위 안 적이 없으면 회색).
- 보고는 실측·추정·미확인을 분리한다(C23 · C5). 커밋은 의도 변경 파일만.
## UI 캔버스·아틀라스 구조 (PD 2026-11-10 「리소스·정보가 얼마나 자주 바뀌는지에 따라 캔버스를 나누어 최적화 · 드로우콜 최소화 구조 필수」)
UI 를 새로 만들거나 고칠 때 **반드시** 이 구조를 따른다(어기면 `Tests/PlayMode/UILayerTests` 가 실패). 조직 전체 표준 = 조직 레포 프로젝트 규칙 **P41**(`.claude/skills/너드나비스-코어룰/rules/P41.md` · 2026-11-10) — 이 절은 그 표준의 이 프로젝트 구현 SOT 이자 다른 프로젝트의 참조 구현이다.
- **갱신 등급 3단**(`Runtime/UI/UiLayer.cs` `UiRate`): **Static** = 화면을 열 때만(바탕 · 틀 · 고정 글자) · **Event** = 조작·게임 사건 때(값 · 선택 · 턴 · 팝업) · **Frame** = 매 프레임(호흡 · 튀김 · 스크롤 내용 · 끌기 · 미니맵 · 커서). 등급이 다른 것은 같은 캔버스에 두지 않는다 — 캔버스는 자식 하나만 바뀌어도 그 캔버스 전체를 다시 묶는다.
- **만드는 법**: 루트 = `UiLayer.Root(go, cam, order, plane, reference, rate)` · 기존 오브젝트를 층으로 = `UiLayer.Nest(go, rate, raycast)` · 빈 층 = `UiLayer.Group(name, parent, rate)` · 매 프레임 요소 = `UiLayer.Isolate(go)`(`UiPulse`·`UiPop` 은 스스로 호출 · 바로 위 부모가 Frame 층이면 그 층에 합침). 중첩 캔버스는 **overrideSorting 끔**(그리는 순서 · `RectMask2D`/`Mask` 자르기 유지) · **누르는 그래픽이 있는 층에만 GraphicRaycaster**(중첩 캔버스의 그래픽은 부모 캔버스 레이캐스터가 못 봄 → 누름 층은 `raycast: true`).
- **현재 배치**: 아웃게임 루트(Static · 바탕 + 하단 탭) → 화면마다 중첩(Event) → `UiKit.ScrollGrid` 내용(Frame · 자동) · 위 덮개 루트 → 재화 바 · 팝업(`ModalCustom`) · 토스트 · 뽑기 결과 · 편성 끌기 유령 각각 중첩 · 전투 결과 루트(Event · 별 줄 = Frame) · 전투 HUD 루트 = 정적 판(칩 바탕 · 유닛 판 바탕 · 미니맵 틀) → `Info`(글자·값·스킬 버튼 · Event) → `Minimap/MinimapLive`(시야·점 · Frame) · `SkillGlow`(Frame) → `Result`(Event) · 월드맵 루트(Static · 띠·넘김·본영) → `Content`(맵·노드 · 스크롤 · Frame) → `cursor`(Frame) · `Popup`(Event).
- **매 프레임 호출되는 갱신 코드**는 값이 같으면 쓰지 않는다(`sizeDelta`·`anchoredPosition`·`CanvasGroup.alpha/interactable` 비교 후 대입 · `Text.text`·`Graphic.color` 는 Unity 가 이미 비교).
- **아틀라스**: 구성 SOT = `Assets/Data/UI/ui_atlas.csv`(theme 줄 = UI 테마가 쓰는 스프라이트를 경로 match 로 · folder 줄 = 폴더 통째 · `single_area` 보다 큰 그림 = 묶지 않음) → `Editor/UIAtlasBuilder` → `Assets/UI/Atlases/*.spriteatlasv2`(UI_Common 4096×2048 · UI_Content 2048×2048 · WorldMap_UI 1024×1024 · 각 1장). **UI 테마 임포트가 끝날 때마다 자동 갱신**(새 납품 스프라이트 = 코드·표 변경 없이 묶임) · 수동 = 메뉴 `TKS/Build UI Atlases (UI 아틀라스 갱신)`. 패커 = Sprite Atlas V2(에디터 Play 에서도 묶임 · `EditorSettings` m_SpritePackerMode 5). 사각 묶음(Tight 끔 · 회전 끔 — 9-slice·Filled 보존). **스프라이트를 잘라 새로 만드는 코드는 `sprite.packed ? sprite.textureRect : sprite.rect`**(`UISkin.WorldSprite` 참고 · `rect` 는 원본 기준).
- **검증**: `-executeMethod TKS.EditorTools.DataImporter.CaptureUI` 캡처 로그에 화면마다 `layers <화면> batches=… canvases=루트+중첩 … frameRebuildGraphics=…` 줄 + `ui_layers.csv`(캔버스별 그래픽 수 · 등급 · 레이캐스터 · 매 프레임 요소 여부 · `Runtime/UI/UiLayerProbe`). 2026-11-10 개선 전→후(13화면 · 1080×1920) = 배치 합계 1124 → 439 · 평상시 매 프레임 재구성 그래픽(전투 HUD 49 → 10 · 월드맵 241 → 1 · 보물 상자 115 → 2 · 전투 결과 115 → 14).
- **남은 드로우콜 원인**(2026-11-10 실측): 영웅 목록(72)·편성(120) = 유닛 초상(유닛 아트 프레임 797×826 · 유닛마다 다른 텍스처라 카드마다 끊김) — 목록용 축소 초상 아틀라스 = **모든 영웅 리소스 제작이 끝난 뒤 진행**(PD 2026-11-10 결정 · 그 전에는 만들지 않는다).
- 같은 PC 의 다른 세션도 `E:\Nerdnavis\_tks_verify` 를 캡처에 쓴다 → 사본은 세션마다 따로(예 `Tools/mirror_verify.py <본체> E:/Nerdnavis/_tks_verify_ui`) · 남이 돌리는 사본에 미러하지 않는다(실행 중 코드가 바뀜).
스킬 이펙트 작업 준비 — 스킬 테스트 씬 · WL 이펙트 이식 · 이펙트 표 · 보병·창·기병 슬링샷 공격 = WL 창 돌진 이펙트 시험(PD 2026-11-09) PD 「WL 프로젝트에서 스킬을 구현하던 방식과 동일하게 유닛 별 스킬 구현」 · 「테스트 목적: 보병, 창, 기병을 슬링샷으로 공격할 때 WL 창 돌진 공격 이펙트」 - 스킬 테스트 씬 Assets/Scenes/SkillTest.unity(SkillTestBootstrap · 메뉴 TKS/Skill Test/Build Scene): 영웅 목록 선택(heroes.csv 56) · 더미(죽지 않음 · 행동 토글 · 배치 표 Resources/Skills/skill_test.csv) · 슬링샷 · 액티브 버튼 · 쿨 무시 · 영웅 무적 · 이펙트 보기(에디터 · Assets/VFX 검색 → 영웅에 띄움) - 이펙트 표 Resources/Skills/skill_vfx.csv → Runtime/Skills/SkillVfx(키 = 스킬 id 또는 basic_<병종> · cast/travel/hit · f_every 반복 · 사본 Resources/Fx/TKS_Fx_*) · 훅 = SkillSystem Announce/BeginAction/EndAction/Hit/Instant - WL 이펙트 이식 Assets/VFX(약 640 MB · 빌트인 호환분만 · GUID 유지 · 도구 Tools/wl_vfx_import.py) · URP 셰이더 빌트인 이식 4종 Assets/VFX/_BuiltinPorts · com.unity.shadergraph 17.3.0 · 카메라 깊이 텍스처 켬(셰이더 그래프 소프트 파티클) - 시험: basic_infantry/spear/cavalry travel = TKS_Fx_SpearRush · SpearRushWrap · SpearRushDust(WL WLStaffEarth rushFx 1~3 값 환산) — 표 9행 삭제 = 원래대로 - 테스트 118/118 · console error 0 · 이 PC 첫 임포트 자동 재직렬화(png·tga .meta · UITheme · ProjectSettings · InputManager)는 제외 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 14:12:52 +00:00
## 스킬 이펙트 작업 (2026-11-09 PD 「WL 에서 스킬을 구현하던 방식과 동일하게 유닛별 스킬 구현」 · 이 PC = 연출 담당)
스킬 이펙트 1차 + IB(쿠로네코) 연출 시험 — 돌진·조준 UI·타격감 (PD 2026-11-10) - 기본 공격(돌진) = IB 이펙트 그대로 시험: 앞 빛 물결 · 속도 꼬리(진영색 4색 · 멈춘 자리에서 0.12초 흐려짐) · WL 흙먼지 · 기준점 dash(아래로 갈수록 발 쪽) · 히트 이펙트 제거(PD 지정 대기) - 슬링샷 방향 결정 UI = IB GameTouchArrow 이식(IbAimArrow · IB 유닛 반지름 0.496 기준 비율) + 진행 중 캐릭터 연출(IbUnitMarks: 발밑 원 · 몸 빛 · 조준 중 속성 방울) · 값 표 Resources/Skills/ib_ui.csv - 기병: 복귀 영역(채운 원 · PreviewCavalryReturn) · 복귀 때 돌아서기(UnitView.TurnAround) - 타격감: HitFeel + CameraController.Shake · 표 hit_feel.csv(IB 흔들림 값은 디컴파일에 없어 추정값) - 액티브 스킬 1차 연출(Fable 제안 56 스킬 · 사본 Resources/Fx/TKS_Fx_Sk_*) · SkillVfx 확장(s_camp · f_fwd · f_drift · f_fade · s_over · b_flat · 트레일 페이드) · 셀화 셰이더 포트 - 2D 돌진 시험본(Dash2D · Aura2D test_aura) · 이전 시험 행은 skill_vfx.csv 에 # 주석 - 여포 크기: dz_boss_lvbu 몸 높이 819 → 718(깃털 제외 · 말 탄 유닛 머리 끝 상한 때문에 작아졌음) - 원본 = Assets/VFX/IB(쿠로네코 · GUID 유지 · Tools/wl_vfx_import.py --skip-scripts) · 사본 도구 Tools/make_ib_fx_copies.cs · make_ib_camp_textures.py · build_dash2d.cs - 테스트 PlayMode 118/118 통과 · 자동 재직렬화(png meta · UITheme · ProjectSettings) 제외 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 04:19:44 +00:00
- **작업 착수 규칙(PD 2026-11-10)**: 지시가 오면 첫 명령 = `unity command --project-path . editor.playmode stop`(씬이 열려 있든 Play 중이든 끄고 바로 착수 · 기다리지 않음) · 지시를 받은 작업은 끝까지 진행(멋대로 멈추지 않음 · 도구 호출이 끊기면 다시 걸어 이어 감).
- **확인 규칙 = 수정한 부분만(PD 2026-11-10 「수정 지시마다 수정한 부분 외 모든 부분을 다 테스트하는 것 같다 → 수정한 부분만」)**: Play 캡처는 그 지시로 바뀐 이펙트·유닛·상황만(예: 「기병 복귀 재생」 = 기병 1기 돌격·복귀만 · 다른 진영·방향·이펙트 재확인 금지) · 자동 테스트는 전투 규칙 코드(ActionResolver · Combat · BattleManager 판정 · SkillSystem 효과)를 바꿨을 때만 그 관련 테스트 클래스만(`test run --filter`) · 표(csv) · 이펙트 사본 · 셰이더 · 테스트 씬 UI 만 바꾼 지시는 자동 테스트 없음 · 전체 테스트(118)는 PD 가 커밋을 지시할 때 1회.
스킬 이펙트 작업 준비 — 스킬 테스트 씬 · WL 이펙트 이식 · 이펙트 표 · 보병·창·기병 슬링샷 공격 = WL 창 돌진 이펙트 시험(PD 2026-11-09) PD 「WL 프로젝트에서 스킬을 구현하던 방식과 동일하게 유닛 별 스킬 구현」 · 「테스트 목적: 보병, 창, 기병을 슬링샷으로 공격할 때 WL 창 돌진 공격 이펙트」 - 스킬 테스트 씬 Assets/Scenes/SkillTest.unity(SkillTestBootstrap · 메뉴 TKS/Skill Test/Build Scene): 영웅 목록 선택(heroes.csv 56) · 더미(죽지 않음 · 행동 토글 · 배치 표 Resources/Skills/skill_test.csv) · 슬링샷 · 액티브 버튼 · 쿨 무시 · 영웅 무적 · 이펙트 보기(에디터 · Assets/VFX 검색 → 영웅에 띄움) - 이펙트 표 Resources/Skills/skill_vfx.csv → Runtime/Skills/SkillVfx(키 = 스킬 id 또는 basic_<병종> · cast/travel/hit · f_every 반복 · 사본 Resources/Fx/TKS_Fx_*) · 훅 = SkillSystem Announce/BeginAction/EndAction/Hit/Instant - WL 이펙트 이식 Assets/VFX(약 640 MB · 빌트인 호환분만 · GUID 유지 · 도구 Tools/wl_vfx_import.py) · URP 셰이더 빌트인 이식 4종 Assets/VFX/_BuiltinPorts · com.unity.shadergraph 17.3.0 · 카메라 깊이 텍스처 켬(셰이더 그래프 소프트 파티클) - 시험: basic_infantry/spear/cavalry travel = TKS_Fx_SpearRush · SpearRushWrap · SpearRushDust(WL WLStaffEarth rushFx 1~3 값 환산) — 표 9행 삭제 = 원래대로 - 테스트 118/118 · console error 0 · 이 PC 첫 임포트 자동 재직렬화(png·tga .meta · UITheme · ProjectSettings · InputManager)는 제외 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 14:12:52 +00:00
- **스킬 테스트 씬** = `Assets/Scenes/SkillTest.unity`(메뉴 `TKS/Skill Test/Build Scene` 로 다시 만듦 · 씬 = `SkillTestBootstrap` 하나) — 전투 코드 그대로 + 월드맵·아웃게임·세이브 없음 · 왼쪽 위 「유닛 선택」(heroes.csv 영웅 56 · 진영별) · 「이펙트 보기」(에디터 전용 · `Assets/VFX` 프리팹 검색 → 고른 영웅 몸에 띄움 · 크기 ×0.25~4 · 기울기 0/−45/−90 · 방향 · 경로 복사) · 왼쪽 아래 「다시 배치」(표 다시 읽기 + 처음 자리) · 쿨 무시 · 더미 행동 · 영웅 무적. 더미 = 죽지 않음(`Unit.Invincible` · 아군 턴마다 체력 회복) · 배치 표 `Resources/Skills/skill_test.csv`(hero 행 n_slot + 상대 좌표) · 더미 행동 끔 = `BattleManager.EnemyHold`. 패널 위 누름은 슬링샷이 무시(`SlingshotInput.BlockPress`).
스킬 이펙트 1차 + IB(쿠로네코) 연출 시험 — 돌진·조준 UI·타격감 (PD 2026-11-10) - 기본 공격(돌진) = IB 이펙트 그대로 시험: 앞 빛 물결 · 속도 꼬리(진영색 4색 · 멈춘 자리에서 0.12초 흐려짐) · WL 흙먼지 · 기준점 dash(아래로 갈수록 발 쪽) · 히트 이펙트 제거(PD 지정 대기) - 슬링샷 방향 결정 UI = IB GameTouchArrow 이식(IbAimArrow · IB 유닛 반지름 0.496 기준 비율) + 진행 중 캐릭터 연출(IbUnitMarks: 발밑 원 · 몸 빛 · 조준 중 속성 방울) · 값 표 Resources/Skills/ib_ui.csv - 기병: 복귀 영역(채운 원 · PreviewCavalryReturn) · 복귀 때 돌아서기(UnitView.TurnAround) - 타격감: HitFeel + CameraController.Shake · 표 hit_feel.csv(IB 흔들림 값은 디컴파일에 없어 추정값) - 액티브 스킬 1차 연출(Fable 제안 56 스킬 · 사본 Resources/Fx/TKS_Fx_Sk_*) · SkillVfx 확장(s_camp · f_fwd · f_drift · f_fade · s_over · b_flat · 트레일 페이드) · 셀화 셰이더 포트 - 2D 돌진 시험본(Dash2D · Aura2D test_aura) · 이전 시험 행은 skill_vfx.csv 에 # 주석 - 여포 크기: dz_boss_lvbu 몸 높이 819 → 718(깃털 제외 · 말 탄 유닛 머리 끝 상한 때문에 작아졌음) - 원본 = Assets/VFX/IB(쿠로네코 · GUID 유지 · Tools/wl_vfx_import.py --skip-scripts) · 사본 도구 Tools/make_ib_fx_copies.cs · make_ib_camp_textures.py · build_dash2d.cs - 테스트 PlayMode 118/118 통과 · 자동 재직렬화(png meta · UITheme · ProjectSettings) 제외 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 04:19:44 +00:00
- **이펙트 값 = 표 `Assets/Resources/Skills/skill_vfx.csv`**(머리 주석이 칸 설명) → `Runtime/Skills/SkillVfx`(전투마다 다시 읽음). 키 = 스킬 id(액티브) 또는 `basic_<병종>`(일반 슬링샷 공격 · 이동만인 추가 이동 제외) · 이벤트 = cast(발동) · travel(슬링샷 돌진 동안 · `f_every` 반복) · hit(그 행동의 피해 순간 · 대상마다 1번). 훅 = `SkillSystem.Announce`(cast) · `BeginAction`/`EndAction`(travel) · `Hit`(hit) · 즉시형 `Instant`. 크기 `f_scale` = 유닛 키 대비(WL 배율 ÷ 1.8 ≈ 같은 비율) · 입자 크기 모드는 띄울 때 전부 Hierarchy · 정렬 = 12 + n_order · 가상 실행(Sim) 중 없음. **돌진(travel) 규칙 = WL `WLStaffEarth.Rush` 와 같게**(2026-11-09 PD 「돌진하는 동안 이펙트가 정상적으로 안 보임」 수정): `b_sustain` 1 = 시간당 방출 층을 반복으로(한 번 띄워 돌진 내내 유지 · 다시 띄우면 0.1~0.2 s 만에 끊김) · `b_clear` 1 = 행동 끝에 남은 입자까지 지움(WL ClearEnd) · `b_face` = 이펙트를 옆모습으로 화면에 눕혀 진행 방향으로 돌림(`SkillVfx.FxRotation` · 3D 세계 그대로 놓으면 위쪽 돌진 때 판 모양 섬광이 옆면만 보임) + `f_tilt` = 진행 축 기준 카메라 쪽 기울기(−35 기본 · −90 = 위에서 본 모습) · 이 게임 돌진은 약 0.3~0.4 s(WL 0.95 s)라 배속은 그 길이에 맞춘다. **2026-11-10 추가**: `s_skill` 은 `;` 로 여러 키 · `s_camp` = 진영(heroes.csv faction shu·wei·wu·other · `Unit.Camp` = 출전 영웅만 · 진영 없는 적 병사 = other) · `f_fwd` = 진행 방향 앞(+)·뒤(−) 위치 · `f_drift` = 입자 자체 이동 배율(스스로 날아가는 데모용 돌진 이펙트를 유닛에 붙일 때 0.1) · 회전 = **프리팹 원본 루트 회전을 살리고 그 진행 축만 화면 방향에 맞춤**(`FxRotation(tilt, face, r0)` — MasterStylizedFX 투사체·Dash 는 루트에 (0, 90, 270) 같은 회전이 있어 덮어쓰면 판이 옆으로 서서 가늘게만 보임) · `n_order` −14 = 유닛 바로 아래(캐릭터가 이펙트 안에 보임 · 바닥 −20~−16 · 사거리 원 −10 · 유닛 0) · 팩 데모용 자리표시(`Character` 큐브)는 사본에서 끈다. 현재 시험(PD 2026-11-10 스크린샷) = 보병·창·기병 돌진: 위 `TKS_Fx_EnergyProjectile`(파랑) · 촉 `GreenProjectile` · 오 `FireProjectile`(주황) · 군 `PurpleProjectile` + 뒤쪽 대쉬 느낌 `TKS_Fx_<Blue|Green|Red|Purple>Dash`(f_fwd −0.6). **URP HDR 근사**: MasterStylizedFX 이식 셰이더는 `_BuiltinPorts/TKS_HdrApprox.cginc` 로 1 넘는 밝기를 흰빛으로(빌트인 · 감마 · 블룸 없음이라 그대로면 평평한 단색 띠).
- **돌진 이펙트 재생 구간 · 소멸(PD 2026-11-10)**: travel 이펙트는 「슬링샷 직진 구간」 동안만 — 보병·창병 = 접촉 순간, 기병 = 관통 끝에 `SkillSystem.DashEnd` 로 멈추고 `f_fade` 초 동안 그 자리에서 흐려져 사라짐(`SkillVfxFade` · 입자 색 알파를 직접 낮춰 수명 무한 층도 사라짐) · 기병 복귀 · 위진소요 추가 관통 = `DashBegin` 으로 그 방향에 다시 재생 → 도착 후 같은 소멸(훅 = `ActionResolver` 의 `DashEnd/DashBegin` 5곳). 튕김 · 밀기 · 반작용 = 반응이라 이펙트 없음.
- **이중 레이어(PD 2026-11-10 「돌진 이펙트 앞부분(머리)은 캐릭터보다 상단 · 레이어 이중 · 돌진 방향만 실드 형태로 일부를 가림」)**: 표 `s_over` = 유닛 위(정렬 12)에 그릴 자식 층 이름(`;` 여러 개) · 나머지 층은 `n_order` 그대로 — 진영 혜성 = `BG;Head (1)`(머리 셸) 위 · 꼬리 −2 · 뒤쪽 Dash −3 · 머리 중심 = 몸 앞 0.6 키(0.2 키 = 상반신을 다 덮음 · 실측).
- **IB(쿠로네코) 이펙트 시험(현재 기본 공격 · PD 2026-11-10 「내가 원한 비주얼은 이런게 아니야(이노센트베인 영상) → 우선 IB 이펙트를 그대로 써서 확인 · 나중에 구조에 맞게 새로 그림(화풍 통일)」)**: IB 슬링샷 발사 `UnitVisualEffectControl.ShowBoosterFX()` 와 같은 구성 — `ef_booster`(앞 빛 물결 2장 + 가시 · 0.2초 반복 맥동 · 유닛 위 · 이동 끝에 바로 지움 = IB Breaking 때 Kill) · `ef_speed_tail`(꼬리 0.6초 + 화살표 입자 · 유닛 아래 · 끝나면 꼬리가 줄며 사라짐 — `SkillVfx.Stop` 이 트레일 길이만큼 기다림) · `ef_booster_dust`(출발 먼지 1번) · 타격 `ef_normal_hit`. 원본 = `Assets/VFX/IB/`(쿠로네코 `E:\NerdNavis\Kuroneko\KuronekoClient` 에서 `Tools/wl_vfx_import.py copy … --wl <쿠로네코> --dest Assets/VFX/IB --skip-scripts` · GUID 유지 · 무수정) · 사본 = `Resources/Fx/TKS_Fx_IB_*`(`Tools/make_ib_fx_copies.cs` — IB 전용 스크립트 부품 제거 · 정렬 레이어 Default · 방향 있는 것은 감싸는 루트 + 안쪽 Z −90°(IB 정면 +Y → 이 게임 +X) · 소리 이벤트 받는 곳 `IbFxAnimEvents`(아무것도 안 함 · 없으면 재생마다 콘솔 오류)). 셰이더 = `Fingar/Additive`(더하기 섞기 · 빌트인 그대로). 2D 돌진 3차 행은 표에 `#` 주석(되돌리기). **진영색(PD 「진영 색을 입히고」)** = `TKS_Fx_IB_Booster_<진영>`(스프라이트 색의 색상만 진영색 · 채도·밝기 유지) · `TKS_Fx_IB_SpeedTail_<진영>`(꼬리 그림 `Assets/VFX/IB/_TKS/Tail_Basic02_<진영>.png` = `Tools/make_ib_camp_textures.py` · 재질 같은 폴더 · 화살표 입자 색) — 둘 다 `make_ib_fx_copies.cs` 가 `Tools/dash2d_camps.csv` 로 만듦 · 원색 사본 `TKS_Fx_IB_Booster` · `SpeedTail` 은 비교용으로 남음(표에서 안 씀). **사라지는 시점(PD 「멈춘 이후 뒤늦게 이펙트가 사라짐 · 위치 안 맞음」)** = 속도 꼬리 `f_fade` 0.12 — 멈춘 자리에서 꼬리째 흐려짐(`SkillVfxFade` 가 트레일 색 그러데이션 불투명도도 낮춤 · 전에는 0.6초 꼬리 머리가 기병 돌격 끝자리에 남아 복귀 중에도 보였음). **타격** = 현재 없음(PD 2026-11-10 「적이 피격되었을 때 히트 이펙트는 제거 · 어떤 히트 이펙트를 쓸지 알려줄게」 · IB NormalHit · BounceHit 행은 표에 `#` 주석). **기준점 `e_anchor` = dash**(빛 물결 · 꼬리 · PD 「복귀할 때 이펙트가 캐릭터보다 위쪽에 생겨 안 보임 → 유닛 바닥에」) = 위·옆으로 갈 때 몸 가운데 · 아래로 갈수록 발 쪽(곧장 아래 = 발). **흙먼지** = WL 창 돌진 흙먼지 `TKS_Fx_SpearRushDust`(0.15초마다 발밑 · PD 「복귀할 때 흙먼지가 너무 세서 뭉개짐 → WL 흙먼지로」 · IB 출발 먼지 행은 `#` 주석).
- **방향 결정 UI = IB 이식(PD 2026-11-10 「IB 와 같이 슬링샷 조작 시 방향 결정 UI 등을 그대로 이식」)**: `TKS.IbAimArrow`(IB `GameTouchArrow` 동작 · 프리팹 `Resources/Fx/TKS_Fx_IB_GameArrow` = 원본 `Assets/VFX/IB/AssetResources/Game/GameArrow` 사본) — 누르면 유닛 둘레 고리 + 퍼지는 고리 3개(3초 · 1초 간격) · 당기면 하늘색 화살표가 쏠 방향으로 돌고 당긴 세기만큼 길어짐(0.5~1.5 · 최소 당김 → 슬링샷 최대 거리) · 화살 끝이 전장 밖이면 안으로 · 놓으면 숨김. 전에 쓰던 조준선 · 당김선은 끔(`SlingshotInput.ShowPreview` · IbAimArrow 가 없을 때만 예전 선). 목표 고리 · 강조 · 궁병 화살 경로선 · 기믹 예상 궤적은 그대로. 화살표 색 = IB 공격 종류 3(하늘색) 하나.
- **여포 크기(PD 2026-11-10 「왜 여포는 다른 기병보다 작지?」)**: 말 탄 유닛은 머리 끝 상한(BalanceConfig.mountedArtMaxTop 1.3 × 표준 키)에 맞춰 줄어드는데, `dz_boss_lvbu` 의 몸 높이(`meta.json` bodyHeightPx · `art_size.csv` body_px)가 머리 깃털 끝까지 819 px 라 몸 전체가 더 줄었음 → 왕관 끝 ~ 발 718 px(front_idle 실측 · 깃털 제외 · 다른 기병의 투구 끝 기준과 같은 규칙)로 고침 → 배율 0.2381 → 0.2716(+14 %). 원본 백업 = 세션 scratchpad. **다른 PC 에서 그림을 다시 export 하면 819 로 되돌아갈 수 있음**(export 규칙 = 불투명 폭 30 % 행 — 깃털이 넓어서 안 걸러짐).
- **근접 3병종 특징 = 한 줄 정의(PD 2026-11-10 직접 지시)**: **보병** = 적을 밀치고 튕겨나며 튕기면서 다른 적을 추가로 공격(알까기 + 연쇄 · #1098 그대로 · 목표점 명중 추가 이동 = 제거(PD #1112 결정 ⑱)) · **창병** = 적을 크게 밀치지만 자신은 적게 밀림(`spearPushRatio` 1.5 > 보병 `collisionPushRatio` 1.0 · 반작용 남은 거리 × 0.3 < 보병 자기 튕김 0.5) · **창병 대기(견제) 제거**(「유저가 인지하기 어려움」 · 목표점 명중해도 `SetOverwatch` 안 함 · HUD 「견제 반경·대기 중」 문구 삭제) · **기병** = 적을 관통해 이동 · **목표점 명중 시 제자리 복귀 제거**(「유저가 인지하기 어려움」 · `PreviewCavalryReturn` · 조준 때 복귀 영역 `ShowReturnZones` 삭제 · AI 가중치 `cav_return`·`cav_stranded` 삭제). 견제·복귀 스킬 = #1112 PD 새 기획으로 전부 재설계(견제 없음 · 복귀는 스킬 효과 `return_on_hit`·`return_always`·`return_aim` 으로만) · `SkillMods.Overwatch*` 삭제 · `BattleManager.ApplyOverwatch` · `Unit.Overwatch` 는 스킬 확장 없이 남음(대기 유닛이 없어 실행 안 됨).
스킬 이펙트 1차 + IB(쿠로네코) 연출 시험 — 돌진·조준 UI·타격감 (PD 2026-11-10) - 기본 공격(돌진) = IB 이펙트 그대로 시험: 앞 빛 물결 · 속도 꼬리(진영색 4색 · 멈춘 자리에서 0.12초 흐려짐) · WL 흙먼지 · 기준점 dash(아래로 갈수록 발 쪽) · 히트 이펙트 제거(PD 지정 대기) - 슬링샷 방향 결정 UI = IB GameTouchArrow 이식(IbAimArrow · IB 유닛 반지름 0.496 기준 비율) + 진행 중 캐릭터 연출(IbUnitMarks: 발밑 원 · 몸 빛 · 조준 중 속성 방울) · 값 표 Resources/Skills/ib_ui.csv - 기병: 복귀 영역(채운 원 · PreviewCavalryReturn) · 복귀 때 돌아서기(UnitView.TurnAround) - 타격감: HitFeel + CameraController.Shake · 표 hit_feel.csv(IB 흔들림 값은 디컴파일에 없어 추정값) - 액티브 스킬 1차 연출(Fable 제안 56 스킬 · 사본 Resources/Fx/TKS_Fx_Sk_*) · SkillVfx 확장(s_camp · f_fwd · f_drift · f_fade · s_over · b_flat · 트레일 페이드) · 셀화 셰이더 포트 - 2D 돌진 시험본(Dash2D · Aura2D test_aura) · 이전 시험 행은 skill_vfx.csv 에 # 주석 - 여포 크기: dz_boss_lvbu 몸 높이 819 → 718(깃털 제외 · 말 탄 유닛 머리 끝 상한 때문에 작아졌음) - 원본 = Assets/VFX/IB(쿠로네코 · GUID 유지 · Tools/wl_vfx_import.py --skip-scripts) · 사본 도구 Tools/make_ib_fx_copies.cs · make_ib_camp_textures.py · build_dash2d.cs - 테스트 PlayMode 118/118 통과 · 자동 재직렬화(png meta · UITheme · ProjectSettings) 제외 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 04:19:44 +00:00
- **IB 크기 · 캐릭터 연출(PD 2026-11-10 「IB 와 화살표 크기도 다르고 선택된 캐릭터 주위 연출도 누락」)**: 값 표 `Resources/Skills/ib_ui.csv`(`TKS.IbUi`) — IB 유닛 반지름 0.496(ExportCharacter size 8 × 0.062) 기준 배율 = 이 게임 유닛 반지름 / 0.496 → 고리 지름 = 반지름 × 5.4 · 화살표 세기 s = IB 월드 당김 × 0.6(0.5~1.5) · IB 취소 거리 0.5. **`TKS.IbUnitMarks`** = 선택한 행동 가능 아군 발밑 도는 원(`TKS_Fx_IB_TargetCircle` · IB ShowUserTurnMark) + 몸 둘레 빛(`TKS_Fx_IB_AttackReady`) · 조준 중(누름 ~ 놓음) 모든 유닛 속성 방울(`TKS_Fx_IB_Attribute_<속성>` · IB SetActiveBarrierVisualEffect · 진영 → 속성 = 표 element_*: 위 물 · 촉 나무 · 오 불 · 군·진영 없음 어둠).
- **타격감(PD 2026-11-10 「화면 흔들림 등도 IB 를 참고해서」)**: `TKS.HitFeel` + 표 `Resources/Skills/hit_feel.csv`(행동 중 유닛이 상대에게 처음 피해를 준 순간 · `SkillSystem.Hit` · 흔들림 = `CameraController.Shake`(추적 위치는 그대로 두고 흔들림만 더함) · 히트 스톱 칸 있음(현재 0)). **IB 실측**: 흔들림 함수 6종은 스킬·궁극기·기믹 이펙트 애니메이션 이벤트로만 불리고 본문이 디컴파일에서 비어 있어 값 없음 · 일반 타격·벽 튕김엔 흔들림 없음 · 히트 스톱 없음 → 표 값(hit 0.15초 · 키 10 % / 기병 0.18초 · 13 %)은 추정.
- **2D 돌진(PD 2026-11-10 「기본 공격(돌진) 이펙트가 너무 3D 느낌 → 2D 처럼」 · MSFX 혜성 행은 표에 `#` 주석으로 남김 = 되돌리기)**: **3차(현재 · PD 2026-11-10 「검기는 이전 형태가 더 나음 · 대쉬 이펙트는 캐릭터 몸을 벗어나지 않도록 · 첨부 같은 느낌으로 몸을 뒤덮는 연출을 스킬용 시험」)** = 초승달 `Head` = 1차 그림 `dash2d_crescent`(검정 외곽선 · 진영색 곱) · 대쉬 층(꼬리 0.04초 · 바람 줄기 · 알갱이 · 흙먼지) = 유닛을 따라 움직이는 Local 공간 · 몸 기준점 반경 0.45 키 안(실측 그림 경계 좌우 ±0.56 · 아래 −0.60 ~ 위 +0.59 키) · 바람 줄기 `Lines` · 알갱이 `Dots` = 유닛 위 반투명(표 `s_over` = `Head;Lines;Dots` · 유닛 아래면 몸에 다 가려 안 보임 · PD 「몸의 대쉬 효과가 왜 안 보이나」) · 꼬리 · 흙먼지 = 유닛 아래 · **기병 복귀 = 돌아서서 감**(`UnitView.TurnAround` · 복귀 방향으로 보기 + 곧장 위·아래면 좌우 반전 · 도착 뒤에도 마지막 이동 방향 PD #1082) · **몸 뒤덮는 기운(시험)** = `TKS_Fx_Aura2D_<진영>`(혜성 기운 `aura_comet_<진영>` 겹쳐 깜빡임 · 불꽃 혀 `aura_wisp` · 반짝임 = 유닛 아래 · 옅은 막 `Veil` · 앞 테 `Rim`(2차 검기 그림) = 유닛 위) · 표 키 `test_aura` · 테스트 씬 「기운 시험」 스위치(`SkillVfx.TestTravelKey` · 켜면 슬링샷 공격 돌진에 함께 · 실제 전투 = 늘 빈칸). 2차 = 외곽선 없음 · 그림 `Assets/VFX/TKS2D/`(만들기 = `python -I -X utf8 Tools/make_dash2d_textures.py` · 진영색 원본 = `Tools/dash2d_camps.csv`) → 프리팹 `Resources/Fx/TKS_Fx_Dash2D_<wei|shu|wu|other>`(검기 초승달 `Head` = 진영별 그림 `dash2d_slash_<진영>` · 유닛 위 · 반투명 꼬리 `Trail`(앞 0.7 → 0) · 흰 바람 줄기 `Lines` · 알갱이 `Dots` = 유닛 아래 · 수명 동안 투명해짐) + `TKS_Fx_Dust2D`(부드러운 반투명 흙먼지 · 모든 진영) · 다시 만들기 = `unity command … script eval --file Tools/build_dash2d.cs`(값을 바꾸면 이 파일과 프리팹을 함께). 1차(검정 외곽선 셀 그림)의 `dash2d_crescent.png` · `dash2d_highlight.png` 는 안 씀. 표 `b_flat` = 1 이면 화면 안에서 진행 방향으로만 돌림(기울기·팩 루트 회전 무시 · `SkillVfx.FlatRotation`) · 크기 단위 = 유닛 키 1(`f_scale` 1) · 끝 소멸 = `f_fade` 0.12(`SkillVfxFade` 가 스프라이트 불투명도도 낮춤).
- **액티브 스킬 1차 연출(PD 2026-11-10 「fable 제안 이펙트 연출을 구현까지 1차로 · 테스트 씬에서 하나씩 피드백」)**: Fable 제안(조직 레포 `공유/기획팀_산출물/삼국지슬링샷/스킬연출_1차_Fable제안_2026-11-10.csv` · 56 스킬 · 138행 · 기믹 14유형) → `skill_vfx.csv` 스킬 id 행(메모 = 원본 경로 · 이유) · 사본 `Resources/Fx/TKS_Fx_Sk_<원본 이름>`(131) + 진영색 안 맞는 10개 = 영웅 전용 보정 사본 `…_<진영>` · WL 추가 이식 1(서황 hit `FX_Whirlwind Ax`). 점검 = 사본 누락 0 · 셰이더 오류 0 · 짧은 이펙트 8 정상 방출(실측). **알려진 한계(PD 확인 대상)**: 아군 전원·적 전원 효과는 시전자 위치에만 표시 · 피해 0 인 매혹·밀기는 hit 이 안 뜰 수 있음 · 장합 변진 도착 연출 지연(f_delay) 없음 · 서황 도끼 뒤 판 메시(`Plane_Trail`)가 정지 시 사각형으로 보일 수 있음 · 색은 YAML 근사 판독(Fable).
- **크기 = 유닛에 맞춤(PD 2026-11-10)**: 혜성 머리 폭(진행 방향에 수직) = 유닛 키 × 1.3(그림 높이 ≈ 키 × 1.17 을 살짝 넘게) — 실측 머리 폭(배율 1.0) 파랑 2.34 · 주황 2.30 · 녹색 2.11 · 보라 2.05 단위 → `f_scale` 0.56 · 0.57 · 0.62 · 0.63 · 머리 중심 = 몸 앞 0.6 키(`f_fwd` · 유닛 아래 층이라 몸 위에 두면 그림에 가려짐) · 뒤쪽 Dash 0.4. 새 이펙트는 같은 방식으로 머리 폭을 재서 정한다(경계 상자 `bounds` 는 입자 시뮬레이션 범위라 실제보다 10배 큼 → 픽셀 측정).
- **색감 · 셀화(PD 2026-11-10 「게임 분위기와 안 맞음」 → Fable 검토 단독 권고 = 이식 셰이더 수정 · 원본 Master Stylized FX 빌트인 셰이더도 수식 동일)**: `TKS_HdrApprox.cginc` = 흰 섞임 상한 `TKS_HOT_MAX` 0.2 · 색 · 불투명도 3단계(`TKS_CEL_STEPS` · 불투명도 반올림 · 보강 `TKS_ALPHA_GAIN` 1.25) · `CommonMeshLoop` 뒷면 셸 = 같은 색 × `TKS_RIM_SHADE` 0.45(고정 갈색은 검은 얼룩으로 보여 바꿈) · 사본 프리팹 진영색 = 위 #3F7FD6 · 촉 #5FAE57 · 오 #E0633A · 군 #9A5BB5(원래 밝기 유지 · 흰 층 제외) · 발광 배수(CustomData Custom1.x) 1·2·5 → 1·1.3·2.
스킬 이펙트 작업 준비 — 스킬 테스트 씬 · WL 이펙트 이식 · 이펙트 표 · 보병·창·기병 슬링샷 공격 = WL 창 돌진 이펙트 시험(PD 2026-11-09) PD 「WL 프로젝트에서 스킬을 구현하던 방식과 동일하게 유닛 별 스킬 구현」 · 「테스트 목적: 보병, 창, 기병을 슬링샷으로 공격할 때 WL 창 돌진 공격 이펙트」 - 스킬 테스트 씬 Assets/Scenes/SkillTest.unity(SkillTestBootstrap · 메뉴 TKS/Skill Test/Build Scene): 영웅 목록 선택(heroes.csv 56) · 더미(죽지 않음 · 행동 토글 · 배치 표 Resources/Skills/skill_test.csv) · 슬링샷 · 액티브 버튼 · 쿨 무시 · 영웅 무적 · 이펙트 보기(에디터 · Assets/VFX 검색 → 영웅에 띄움) - 이펙트 표 Resources/Skills/skill_vfx.csv → Runtime/Skills/SkillVfx(키 = 스킬 id 또는 basic_<병종> · cast/travel/hit · f_every 반복 · 사본 Resources/Fx/TKS_Fx_*) · 훅 = SkillSystem Announce/BeginAction/EndAction/Hit/Instant - WL 이펙트 이식 Assets/VFX(약 640 MB · 빌트인 호환분만 · GUID 유지 · 도구 Tools/wl_vfx_import.py) · URP 셰이더 빌트인 이식 4종 Assets/VFX/_BuiltinPorts · com.unity.shadergraph 17.3.0 · 카메라 깊이 텍스처 켬(셰이더 그래프 소프트 파티클) - 시험: basic_infantry/spear/cavalry travel = TKS_Fx_SpearRush · SpearRushWrap · SpearRushDust(WL WLStaffEarth rushFx 1~3 값 환산) — 표 9행 삭제 = 원래대로 - 테스트 118/118 · console error 0 · 이 PC 첫 임포트 자동 재직렬화(png·tga .meta · UITheme · ProjectSettings · InputManager)는 제외 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 14:12:52 +00:00
- **이펙트 사본 규칙(WL `WL_Fx_*` 와 같음)**: 게임이 읽는 것 = `Assets/Resources/Fx/TKS_Fx_<이름>.prefab` 사본만(메뉴 `TKS/VFX/Make Skill Fx Copy` · 고른 프리팹 → 사본) · 원본 팩 `Assets/VFX/**` 는 고치지 않는다.
- **WL 리소스 옮기기** = `Tools/wl_vfx_import.py`(scan · copy · unpack · `--wl <WL 루트>` · GUID 유지 · URP 전용 셰이더 재질 프리팹은 자동 제외 · WL 원본 무수정) → 에디터 새로고침 → 메뉴 `TKS/VFX/Check Imported VFX`(분홍 재질 · 빠진 스크립트). 판정 표 = `Assets/VFX/_wl_import_report.csv`. 2026-11-09 옮긴 것 = VFX_Klaus(Hyper Casual 1·2 · Shoot&Hit 1·2 · Earth Skills · Element Splash 3) · Lana Casual RPG VFX · Slash Effects FREE · EricWang 4묶음 중 빌트인 통과분 · MasterStylizedProjectiles 통과분 · Kyeoms 폭발 · GAP 툰 투사체(빌트인 패키지 unpack) · WL 창 돌진 사본 3(`Assets/VFX/WL/`) = 약 640 MB.
- **URP 셰이더 이식판** = `Assets/VFX/_BuiltinPorts/*.shader`(원본과 같은 GUID · 셰이더 이름 · 속성 → 옮겨 온 재질이 그대로 사용 · 현재 Eric AdditiveFlow · AlphaBlendFlow · MasterStylizedFX EmissiveParticle · CommonMesh2Side). 새로 필요한 URP 셰이더는 같은 방식으로 이식하면 `wl_vfx_import.py` 가 통과(port)로 본다.
- **카메라 깊이 텍스처 켬**(`GameBootstrap` · `SkillTestBootstrap` `depthTextureMode |= Depth`): Hyper Casual 등 셰이더 그래프의 소프트 파티클이 `_CameraDepthTexture` 를 읽음 — 없으면 이펙트가 안 보이거나 불투명 하늘색 덩어리(2026-11-09 실측). 셰이더 그래프 재질은 `com.unity.shadergraph 17.3.0`(Built-In 타깃) 필요.
## 유닛 아트 반영 (다른 세션의 원화·애니 → 이 게임)
- 아트 위치 = `Assets/Resources/Units/<art>/<clip>/f000.png …` + `meta.json`(fps · ppu · pivot(발) · charHeightPx · clips). `<art>` 는 `BalanceConfig.asset` 의 `heroes[].art` / `stages[].enemies[].art`(비면 도형). 아군 = `liubei`·`guanyu`·`zhangfei`·`zhaoyun`·`huangzhong`(2026-11-04 재디자인 원화 · 스켈레탈 B단계 전까지 front_idle 정지 1장 · 납품 후 리그 v2 12 클립으로 교체) · 적 = `<세력>_<병종>`(`hgj_infantry` …) · 보스 = `<세력>_boss_<로마자>`(`hgj_boss_zhangjiao` …).
- 스켈레탈 리그 → 프레임: 조직 레포 스킬 `skeletal-anim-pipeline/files/scripts/rig_frames_export.py rig <리그 패키지> --parts <작업>/parts --out Assets/Resources/Units/<art> --clips back_idle,back_ready,back_action,back_damage,back_stop,front_idle,front_ready,front_action,front_damage,front_stop,front_victory,front_failed --px 180 --step 2`(ComfyUI venv python · 실측 482×470 · 15 fps · 3인 11 MB).
전투 로직 #1080 — 알까기 충돌(보병) · 관통·아군 직전 정지(기병) · 밀며 함께 전진(창병) · 밀린 아군 공격 기회 · 궁병 제자리 사격(사거리 = 슬링샷)+접근 20 % · 궁수 근접 피해 50 %/피격 +50 % · 원화 1차·2차 반영(전장 배경 + 황건적 5 + 동탁군 4) · 테스트 22/22 - ActionResolver 전면 재작성: InfantryRoutine(접촉점 정지 · Push 접촉 방향 × collisionPushRatio · 적이면 공격+반격 뒤 밀림) · SpearRoutine(앞 유닛과 같은 속도로 함께 전진 · 접촉 간격 유지) · CavalryRoutine(벽만 막음 · StopBeforeUnclearedAllies) · ArcherRoutine(AttackRange = 슬링 · ArcherMoveAllow = 슬링 × archerRangeRatio) · PushedAllyAttack(규칙 ⑤ · ActionOutcome.Pushed/Notes) - Combat: Damage(melee) 궁병 근접 배율(근접 유닛 상대만) · FirstUnitOnPath · TouchingOpponent · FreeTravel ignore - BalanceConfig/Defaults: archerMeleeDealtRatio 0.5 · archerMeleeTakenRatio 1.5 · collisionPushRatio 1 · boardArt battlefield_01 (자산 재시드) - Board: Resources/Board/<boardArt> 원화 배경(격자·진영 띠 생략) · UnitArtImporter Board 규칙 · GameBootstrap - Resources/Units: hgj_infantry·spear·cavalry·archer·boss_zhangjiao · dz_infantry·spear·cavalry·archer (원화 세션 납품 정지 그림 · rig_frames_export static) · Resources/Board/battlefield_01.png - BattleManager Describe 「밀어냄 · 밀린 B → 적 공격」 · BattleHUD 궁병 줄 · 테스트 22종(신규·개정 7 + 원화 확인) · CLAUDE.md · README Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-04 06:56:02 +00:00
- 정지 그림(적 SD 전신 `_rgba.png`) → `rig_frames_export.py static <png> --out Assets/Resources/Units/<art>`(front_idle 1장 · 발 = 불투명 상자 아래). 원화 세션 납품 = `C:\ArtRnD\samguk_game\manifest.json` · 파일명 `<art>_rgba.png` → `<art>` 폴더(2026-11-04 1차 `hgj_*` 5종 + 2차 `dz_infantry·spear·cavalry·archer` 반영 완료 · 여포 `dz_boss_lvbu`·`cc_*`·`wei_*` 는 납품 시 같은 명령).
- 전장 배경 = `Assets/Resources/Board/<boardArt>.png`(자산 `boardArt` · 5:8 불투명 · PPU 100 = 전장 20×32) → `Board.Build` 가 있으면 바닥으로 쓰고 격자·진영 띠는 생략. 임포트 규칙(스프라이트 · 4096 · 압축)은 같은 `UnitArtImporter` 의 `Board/` 분기 · 재임포트 메뉴가 두 폴더 처리.
- 임포트 설정은 `Editor/UnitArtImporter.cs`(AssetPostprocessor · meta 의 pivot·ppu) 가 자동 적용 · 프레임을 넣거나 meta 를 바꾼 뒤 = 메뉴 `TKS/Reimport Unit Art`(Build/BuildFresh 가 함께 호출).
- 재생 = `UnitArt.cs`(Resources 로더 · 캐시) + `FrameAnimator`(대기 loop · 준비 = 조준 중 · 공격·피격 = 1프레임 자세 유지 후 대기 · 승리 = 끝 프레임 유지). **포즈 규칙(PD #1084 · 2026-11-05)**: 공격 애니 대신 1프레임 포즈 전환 — 조준(당기는) 중 = `ready`(출발 자세) · 슬링샷 이동(돌진) 중 = `action`(병종 돌진 포즈 · `UnitView.SetCharging` · `ActionResolver.Resolve` 가 루틴 전후로 켜고 끔) · 멈추면 `idle`. 돌진 중 피격은 색만 바뀜. **4방향 보기(PD #1082)**: `UnitView.SetFacing(dir)` — 마지막 이동 방향의 세로 성분으로 `back_*`(위 ↖↗) / `front_*`(아래 ↙↘) 세트를, 가로 성분으로 `flipX`(왼쪽 = 반전 · 오른쪽 = 기본)를 정한다. 시작 = 아군 ↗ · 적군 ↘. `ActionResolver.Face()` 가 이동·튕김·밀림·돌진·사격·밀린 아군 공격 때 호출(기병 복귀는 방향 유지). 없는 클립은 다른 보기 → 대기로 대체. 세로 크기 = `unitArtHeight`(자산) × 반지름 배율 · 발 = 원 중심 아래 0.55 R.
## 구조 (README 와 동일)
- `Assets/Scripts/Runtime/` — `GameBootstrap`(씬 구성) · `BattleManager` · `ActionResolver` · `Combat` · `SlingshotInput`(조작·스크롤·줌) · `RangeIndicator`(사거리 원·궁병 도넛) · `CameraController`(넓은 전장 카메라) · `EnemyAI`(교전 범위) · `BattleHUD`(HUD·미니맵) · `Unit`/`UnitView` · `UnitArt`(아트 로더·`FrameAnimator`) · `Board` · `Fx` · `AutoPlayDriver`
- `Assets/Scripts/Editor/` — `ProjectSetup`(CLI 진입점·씬 생성) · `BalanceDefaults`(최초 시드) · `StageImporter`(스테이지 표 → 자산) · `UnitArtImporter`(아트 임포트 설정) · `DataImporter`(아웃게임 표 → 자산 · 화면 캡처)
아웃게임 2차(PD #1093 세션 C) — 내정(훈련·순찰·개발) · 보물(수집품·세트·상자) · 연무장(탑·일일 던전·투기장·적장 토벌) · 거래 상자 탭 + 영웅 56명 확장(PD #1096 · 신규 effect_key 4) - 데이터: C 표 10장(training · training_ranks · patrol · dev_tree · treasures · treasure_sets · chests(+iron/buy 열) · tower · dungeons(+reward_amount) · arena(+상점 키)) + economy.csv C 키 24 → 임포트 18 자산(OutGameTables.C.cs 검증: 행·연속 Lv/랭크/층·참조·확률 합 1·선행 노드·효과 키 처리기·카운터 키 · 오류 시 자산 불변) - 영웅 56명: heroes 71 · skills 112 · hero_gear 1344 · gacha_pool 71 재복사 · 신규 키 4(team_dmg_pct_turn · cooldown_add · charm · heal_self_pct) + 기존 키 조건 열(받는 피해 p2 HP 임계/보스/근접 · p3 출전 인원 아군 전원 · 최대 HP·반격 아군 전원 · 피해 % 발동 턴) · 대장군 키는 표 미사용(처리기 유지) - 내정: 훈련(병종 5 · 3항목 Lv · cost_mult · 랭크 승급 · train_bonus → §3-2 항목별) · 순찰(챕터 행 × 시간 · 오프라인 · 상한 12h + 농업 · 소수점 이월 · 광고 2배 스텁 · 즉시 수확 보옥) · 개발(갈래 3 · 선행 · 골드·도면 비용 · 효과 키 → 군량·보상·상점·순찰·상자 적용 지점 · 초기화 보옥 + 도면 환급) - 보물: 보유 중(4열 · 등급 색 · 상세·강화) · 세트(단계 효과) · 상자(포인트 → 명장 · 확률 · 중복 조각) · 효과 hp/atk/def → HeroRules · crit/range/splash → BattleManager.SideEffectsProvider → SkillMods · 조건 카운터 8종 = Runtime/BattleEvents(전투 코드 Raise 1줄씩 · 아군만) · 스테이지 청동 상자 10 % - 연무장: BattleManager.StartMode(BattleMode = 적 편성·제한 턴·onExit) · 탑 100층(입장권·층 배율·보상·10층 상자) · 던전 3(요일·2/일·보상) · 투기장(샘플 10 · EnemyAI 방어 · 메달·주간 순위·조각 상점) · 적장 토벌(주간 순환·hp ×20·5턴·누적 피해·명장 상자·천기) · 결과 패널 → 탭 = 연무장 - 거래: 상자 탭(구매 = 골드/보옥/포인트 · 거래 할인) · 패스·월정액·챕터 팩·첫 결제 팩 = 준비 중 스텁 · 스킬서 임시 판매 제거(사당 던전) - 테스트 87/87(기존 73 유지 · 갱신 3 = 로비 탭 · 표 키 목록 · 상점 스킬서 칸 / 신규 14 = OutGameCTests 12 + 확장 키 2) · console error 0 · 캡처 = DataImporter.CaptureC Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 15:22:54 +00:00
- `Assets/Scripts/OutGame/` — 아웃게임(세이브·로비·영웅·편성·거래·보상 · 내정 `Domestic/` · 보물 `Treasure/` · 연무장 `Arena/` · 위 「코드 규칙」)
- `Assets/Data/Stages/` — 챕터·스테이지 표 CSV 4장(위 「코드 규칙」) · 해석·배치 = `Runtime/StageTable`
- `Assets/Resources/Units/<art>/` — 유닛 아트 프레임 + meta.json(위 절)
스킬 시스템(PD #1093 세션 B) — skills.csv effect_key 51종 처리기 · 액티브(예약/즉시)·패시브 · HUD 스킬 버튼 · 적 무장 패시브 · 스킬 레벨업·스킬서 - 데이터: SkillInfoDb(= 스킬 DB) 에 effect_key·p1~p3(pMask)·lv_scale·needs_impl 추가 · 임포터 검증(trigger · 키 51종 · p 칸 · skill_levels 연속 · lv_max) · skill_levels = levels(비용 표) - 처리기 Runtime/Skills: SkillKeys(51종 · 레벨 계수 = 값×계수 / 배율은 1 넘는 몫 / 횟수 반올림 / 켜기·치환 고정 · 팀 키) · SkillDef·SkillCatalog · SkillSystem(유닛별 쿨·예약 · 즉시형 시한 효과 이번 아군 턴/이번 적 턴 · 행동 훅 · 호위 분담 · HUD 한 줄) · SkillMods(전투 코드 수치 질의) · SkillRules(상한 = 등급 + ★3 액티브 +1 · ★5 패시브 ×1.5 = evolve.csv · 레벨업 · 스킬서 판매) - 전투 연결: ActionResolver(밀기·튕김·추가 이동 n·추가 이동 공격·충돌 추가 피해·밀며 전진 ×·삼첨도·관통 피해/넉백/반격 없음/빗나가도 복귀/한 번 더 관통·사거리·사선 통과·크리·광역 반경/비율/아군 0·백기습영 이동 후 사격·군령/대장군 공격 횟수) · Combat(상성 하한·공 %·주는/받는 피해·근접 패널티 해제·반격 배율/받는 반격·견제 배율) · BattleManager(편성·적 무장 부착 · 견제 반경/횟수/무제한/회복 · 교전 반응 정지 · 교전 범위 · 즉시형 실행) · EnemyAI·RangeIndicator(슬링·사거리 스킬 반영) - UI: HUD 스킬 버튼(이름·Lv·쿨·사용 가능/불가·패시브) · 탭 = 예약/취소/즉시 · 조준 중 2손가락 탭 · 발동 = 이름 글자 + 플래시 · 스킬 한 줄 · 예약 배지 · 변진 반경 원 · 영웅 상세 스킬 레벨업 팝업 · 거래 상점 스킬서 칸(임시) - 표: economy.csv start_skill_books 10 · skill_book_shop_daily 3 · skill_book_price 300(임시 · PD 확인) - 테스트 73/73(기존 56 + SkillTests 17 · 51종 전부) · console error 0 · 캡처 = DataImporter.CaptureSkills Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 14:31:27 +00:00
- `Assets/Scripts/Runtime/Skills/` — 스킬 처리기(위 「코드 규칙」 스킬)
지형 기믹 레이어(PD #1097 세션 D) + 병종 규칙 개정 2건 · 예측 시뮬레이션 적 AI(PD #1098) - 데이터: Assets/Data/Gimmicks/{gimmicks,stage_gimmicks,tutorial_tips}.csv + Assets/Data/AI/ai_weights.csv(기획 tables/ 사본) → 메뉴 TKS/Import Gimmicks(검증 · 오류 시 자산 불변) → Resources/Gimmicks/GimmickDb(16)·StageGimmickTable(16 + 팁 3) · Resources/AI/AiWeights(32) - 레이어: GimmickLayer(전투 시작 = 스테이지 배치 · 배경 위 유닛 아래 · 원/사각/다각 · 색 도형 + 글자 · 내구 핍 · 강 콜라이더 = 다리 구간 제외 · 겹친 유닛 보정) · 장애물 = 병종별 내구 피해·튕김·창 목책 밀기·바위 굴림·기병 정지 · 투사체 pass/block/destroy · 폭약 광역(아군 포함)+밀기+불 · 책사 광역 덤불 제거 · 강 낙하 - 지대: 경로 스윕(독 1→2→3 % · 늪 ×2 · 불 10 % · 빙판 미끄러짐 · 고지 · 안개 · 군기 · 함정) · 양 진영 턴 시작 훅 - 규칙 개정: 보병 튕김 중 다른 적과 연쇄 1회 · 창병 반작용(spearRecoilRatio · 밀며 전진 폐기) · 기존 테스트 기대값 갱신 - 적 AI: Runtime/AI(Sim 가상 실행 · TacticalAI 후보·점수·난이도·턴 운영 · 1부 보스 액티브) · 조준선 = 가상 실행 예상 궤적·기믹 반응·지대 띠 · TKS/Gimmick Painter · 캡처 GimmickImporter.Capture - 검증: 컴파일 0 · 플레이모드 113/113(신규 26) · console error 0 · 적 10기 턴 결정 62 ms Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 16:20:07 +00:00
- `Assets/Scripts/Runtime/Gimmicks/` — 지형 기믹 레이어(위 「코드 규칙」) · `Assets/Scripts/Runtime/AI/` — 예측 시뮬레이션 적 AI(`Sim` · `TacticalAI` · `AiWeights`)
- `Assets/Data/Gimmicks/` · `Assets/Data/AI/` — 기믹 표 3장 · AI 가중치 표
- `Assets/Tests/PlayMode/` — `BattleFlowTests` · `OutGameTests` · `SkillTests` · `OutGameCTests` · `GimmickTests` · `TacticalAITests` · `UILayerTests`(캔버스 층·아틀라스 구조 · 2026-11-10 · 전체 119)
- `.claude/skills/` — Unity CLI 에이전트 스킬(`unity skill install claude-code --local` 산출물 · 재설치는 `unity skill refresh`)