ThreeKingdomsSlingshot/Assets/Scripts/Runtime/WorldMapScreen.cs

958 lines
45 KiB
C#
Raw Permalink Normal View History

시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
using UnityEngine;
using UnityEngine.UI;
namespace TKS
{
// ---------- 데이터(Resources/ChapterMap/Data/world.json · 원화 세션 chap_install.py 생성 · 좌표 = 맵 px · 왼쪽 위 원점 · y 아래로) ----------
// 맵 그림·길 = world.json(맵 id 별) · 노드 자리 = Data/<맵>.json 의 stages[].at(기획 확정판 · 없으면 slots_N) · 게임 챕터·스테이지·노드 수 = BalanceConfig.chapters·stages(스테이지 표 CSV)
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
[Serializable]
public class WorldKitItem
{
public string name;
public float[] pivot; // 이미지 좌표(위 → 아래) 비율
public float[] refSize; // UI 기준 px
public float[] numberCenter; // 번호 자리(이미지 좌표 비율)
}
[Serializable]
public class WorldLandmark
{
public string ko;
public float x;
public float y;
public string role;
}
[Serializable]
public class WorldChapter
{
public string id;
public int no;
public string ko;
public string years;
public string map;
public float[] roadX;
public float[] roadY;
public WorldLandmark[] landmarks;
// world.json 의 nodes·stageLink(구 임시 연결 spec/stage_plan.json) 는 읽지 않는다 — 노드 = 스테이지 표(2026-11-05 145 스테이지)
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
}
[Serializable]
public class WorldData
{
public float[] mapSize;
public float[] viewSize;
public float dotSpacing;
public float[] flagStars; // x0,y0,x1,y1,… (노드 기준 · y 아래로)
public float[] flagBossStars;
public float[] flagCursor;
public float[] flagBossCursor;
public float[] flagFrame;
public bool showLabels; // 장소 이름판 표시(그림 속 장소 위치와 맞춘 뒤 켬)
public WorldKitItem[] kit;
public WorldChapter[] chapters;
public const string Path = "ChapterMap/Data/world";
public const string DataRoot = "ChapterMap/Data/";
public WorldChapter FindMap(string map)
{
if (chapters != null)
foreach (var c in chapters)
if (c.map == map) return c;
return null;
}
/// <summary>Data/&lt;map&gt;.json 의 stages(기획 확정판 맵 · 스테이지 번호·보스·지명·노드 좌표 at). 없으면 null.</summary>
public static AnchorStage[] AnchorStages(string map)
{
var t = Resources.Load<TextAsset>(DataRoot + map);
if (t == null) return null;
try
{
var f = JsonUtility.FromJson<AnchorFile>(t.text);
return f != null && f.stages != null && f.stages.Length > 0 ? f.stages : null;
}
catch (Exception e)
{
Debug.LogWarning("[TKS] " + DataRoot + map + " stages 읽기 실패: " + e.Message);
return null;
}
}
/// <summary>Data/&lt;map&gt;.json(원화 세션 anchors) 의 slots_n(맵 px · 첫 칸 = 출발). 없으면 null.</summary>
public static Vector2[] AnchorSlots(string map, int n)
{
var t = Resources.Load<TextAsset>(DataRoot + map);
if (t == null || n <= 0) return null;
var m = Regex.Match(t.text, "\"slots_" + n + "\"\\s*:\\s*\\[((?:\\s*\\[[^\\]]*\\]\\s*,?)*)\\s*\\]");
if (!m.Success) return null;
var nums = Regex.Matches(m.Groups[1].Value, @"-?\d+(?:\.\d+)?(?:[eE][-+]?\d+)?");
if (nums.Count != n * 2) return null;
var res = new Vector2[n];
for (int i = 0; i < n; i++)
res[i] = new Vector2(float.Parse(nums[2 * i].Value, CultureInfo.InvariantCulture), float.Parse(nums[2 * i + 1].Value, CultureInfo.InvariantCulture));
return res;
}
/// <summary>점 p 에 가장 가까운 길 위 지점의 호 길이.</summary>
public static float ArcOf(WorldChapter c, float[] acc, Vector2 p)
{
int m = acc.Length;
if (m == 1) return 0f;
float best = float.MaxValue, res = 0f;
for (int i = 1; i < m; i++)
{
var a = new Vector2(c.roadX[i - 1], c.roadY[i - 1]);
var b = new Vector2(c.roadX[i], c.roadY[i]);
var ab = b - a;
float t = Mathf.Clamp01(Vector2.Dot(p - a, ab) / Mathf.Max(ab.sqrMagnitude, 1e-6f));
float d = (a + ab * t - p).sqrMagnitude;
if (d < best)
{
best = d;
res = acc[i - 1] + (acc[i] - acc[i - 1]) * t;
}
}
return res;
}
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
public static WorldData Load()
{
var t = Resources.Load<TextAsset>(Path);
if (t == null) return null;
try
{
return JsonUtility.FromJson<WorldData>(t.text);
}
catch (Exception e)
{
Debug.LogError("[TKS] world.json 읽기 실패: " + e.Message);
return null;
}
}
public WorldKitItem Kit(string name)
{
if (kit != null)
foreach (var k in kit)
if (k.name == name) return k;
return null;
}
/// <summary>길(road) 을 호 길이로 n 등분한 노드 자리(맵 px). 첫 칸 = 출발 · 마지막 = 보스.</summary>
public static Vector2[] Slots(WorldChapter c, int n)
{
var acc = Arc(c);
var res = new Vector2[Mathf.Max(0, n)];
float total = acc[acc.Length - 1];
for (int i = 0; i < res.Length; i++) res[i] = At(c, acc, n <= 1 ? 0f : total * i / (n - 1));
return res;
}
public static float[] Arc(WorldChapter c)
{
int m = Mathf.Min(c.roadX.Length, c.roadY.Length);
var acc = new float[Mathf.Max(1, m)];
for (int i = 1; i < m; i++)
acc[i] = acc[i - 1] + Vector2.Distance(new Vector2(c.roadX[i - 1], c.roadY[i - 1]), new Vector2(c.roadX[i], c.roadY[i]));
return acc;
}
public static Vector2 At(WorldChapter c, float[] acc, float len)
{
int m = acc.Length;
if (m == 1) return new Vector2(c.roadX[0], c.roadY[0]);
for (int i = 1; i < m; i++)
{
if (acc[i] >= len)
{
float t = (len - acc[i - 1]) / Mathf.Max(acc[i] - acc[i - 1], 1e-4f);
return Vector2.Lerp(new Vector2(c.roadX[i - 1], c.roadY[i - 1]), new Vector2(c.roadX[i], c.roadY[i]), t);
}
}
return new Vector2(c.roadX[m - 1], c.roadY[m - 1]);
}
}
/// <summary>Data/&lt;맵&gt;.json 의 stages 한 칸(챕터맵 보강 세션 기획 확정판 · 기획서 §4 번호·유형·지명 + 노드 좌표).</summary>
[Serializable]
public class AnchorStage
{
public int stage;
public bool boss;
public string place;
public string title;
public float[] at; // 맵 px(왼쪽 위 원점 · y 아래로)
}
[Serializable]
public class AnchorFile
{
public AnchorStage[] stages;
}
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
public enum NodeState { Lock, Open, Clear }
/// <summary>노드 자리 출처: 기획 확정판 stages[].at · 가안 slots_N · 길 위 균등(대체).</summary>
public enum NodeSource { Stages, Slots, Road }
아웃게임 1차(PD #1093 세션 A) — 본영 로비 · 세이브 · 군량 · 영웅(레벨·승급 6칸·진화·스킬 표시) · 편성(전열 3/후열 2 · 프리셋 3) · 거래(뽑기·골드 장비 상점) · 스테이지 보상·별 3·소탕 - 데이터: 기획 tables/ 12장 → Assets/Data/OutGame/*.csv · 메뉴 TKS/Import OutGame Data(Editor/DataImporter) → Resources/OutGame 9 자산(HeroDb·GearDb·GachaConfig·EconomyConfig·RewardTable·LevelTable·PromotionTable·EvolveTable·SkillInfoDb) · 검증(행 수·필수 열·id 유일·hero↔skill↔gear·확률 합) 오류 시 자산 불변 · BalanceConfig.heroes[]/HeroDef 삭제 → HeroDb(기존 5인 id 유지) · economy.csv 키 17 + gacha.csv 키 2 추가(기획서 본문 값 · C45) - 세이브: persistentDataPath/save.json · ver 1 · 즉시 저장 · 오프라인 군량 회복 · 일일 초기화 · 신규 유저 = 유비·관우·장비·조운·황충 Lv1 녹 ★=희귀도 · 골드 1000 · 보옥 300 · 군량 30 · 테스트·캡처 = 메모리 전용 - 화면(uGUI 와이어프레임 · img03·06·08·11): 시작 = 본영 로비(출정 → 월드맵 · 편성 · 연무장/보물/내정 준비 중 · 동맹 추후) · 재화 바(월드맵 포함 · 군량 타이머) · 하단 탭 5 · ◀/Esc 일관 · 영웅 목록·상세·상세정보·도감 · 편성(탭·드래그) · 뽑기(천장 n/80 · 확률 공개 · 첫 10연 무료 · 10연 ★★ 보장 · 카드 순차 공개) · 장비 상점(흰/녹 6종 일일 · sell×5 · 새로고침 보옥 20) - 전투 연결: BattleManager.LineupProvider/Deployed(LineupEntry · §3-2 스탯 · 방어 배율 생성 뒤) · playerSpawnPoints = 전열 (−4/0/4, −12) · 후열 (−2/2, −14) · WorldMapScreen 훅(팝업 군량·보상·별 · 입장 군량 · 노드 별 star_on/off · 소탕 · ◀ 본영 · TopInset) · 결과 패널(별 3 조건 · 골드·경험·보옥·장비) · GameBootstrap/AutoPlayDriver 로비 시작 - B 세션 파일(ActionResolver·Combat·UnitView·BattleHUD·SlingshotInput·EnemyAI) 미변경 - 테스트 56/56(기존 41 유지 · 신규 OutGameTests 15) · console error 0 · 사본 GUI 캡처 11장(DataImporter.CaptureOutGame) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:11:10 +00:00
/// <summary>진행도(실행 중 메모리) · 챕터별 깬 노드 수. 시작 때 아웃게임 세이브(stages)에서 채운다(OutGameSession.SyncWorldProgress · #1093).</summary>
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
public static class WorldProgress
{
static readonly Dictionary<int, int> cleared = new Dictionary<int, int>();
public static int Cleared(int chapter)
{
int v;
return cleared.TryGetValue(chapter, out v) ? v : 0;
}
public static void MarkCleared(int chapter, int node)
{
if (node + 1 > Cleared(chapter)) cleared[chapter] = node + 1;
}
public static void Reset()
{
cleared.Clear();
}
}
/// <summary>
/// 게임 시작 화면 = 챕터 월드맵(스크롤 · 상하좌우로 끌기). 길 위 깃발 노드를 누르면 스테이지 팝업 → 출전 = 전투 시작 ·
/// 전투 결과를 탭하면 월드맵으로 돌아와 다음 노드가 열린다. 그림·길·부품 배치 = world.json · 노드 자리 = Data/&lt;맵&gt;.json stages[].at(없으면 slots_N → 길 위 균등) ·
/// 챕터·노드·전투 = BalanceConfig.chapters·stages(스테이지 표 · C45) · 보스 노드 = type boss.
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
/// </summary>
public class WorldMapScreen : MonoBehaviour
{
public static WorldMapScreen Instance { get; private set; }
const string UiRoot = "ChapterMap/UI/";
const string MapRoot = "ChapterMap/Maps/";
static readonly Color Ink = new Color(0.14f, 0.09f, 0.07f);
static readonly Color Paper = new Color(1f, 0.98f, 0.93f);
BattleManager battle;
BattleHUD hud;
SlingshotInput sling;
WorldData data;
BalanceConfig cfg;
readonly List<int> nodeStages = new List<int>(); // 현재 챕터 노드 → stages 인덱스
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
GameObject root;
CanvasGroup group;
ScrollRect scroll;
RectTransform viewport;
RectTransform content;
Image mapImage;
Text bannerText;
Button prevButton;
Button nextButton;
RectTransform cursor;
Vector2 cursorBase;
readonly List<GameObject> spawned = new List<GameObject>();
readonly List<Button> nodeButtons = new List<Button>();
GameObject popup;
Text popupTitle;
Text popupBody;
Button popupGo;
Text popupGoLabel;
아웃게임 1차(PD #1093 세션 A) — 본영 로비 · 세이브 · 군량 · 영웅(레벨·승급 6칸·진화·스킬 표시) · 편성(전열 3/후열 2 · 프리셋 3) · 거래(뽑기·골드 장비 상점) · 스테이지 보상·별 3·소탕 - 데이터: 기획 tables/ 12장 → Assets/Data/OutGame/*.csv · 메뉴 TKS/Import OutGame Data(Editor/DataImporter) → Resources/OutGame 9 자산(HeroDb·GearDb·GachaConfig·EconomyConfig·RewardTable·LevelTable·PromotionTable·EvolveTable·SkillInfoDb) · 검증(행 수·필수 열·id 유일·hero↔skill↔gear·확률 합) 오류 시 자산 불변 · BalanceConfig.heroes[]/HeroDef 삭제 → HeroDb(기존 5인 id 유지) · economy.csv 키 17 + gacha.csv 키 2 추가(기획서 본문 값 · C45) - 세이브: persistentDataPath/save.json · ver 1 · 즉시 저장 · 오프라인 군량 회복 · 일일 초기화 · 신규 유저 = 유비·관우·장비·조운·황충 Lv1 녹 ★=희귀도 · 골드 1000 · 보옥 300 · 군량 30 · 테스트·캡처 = 메모리 전용 - 화면(uGUI 와이어프레임 · img03·06·08·11): 시작 = 본영 로비(출정 → 월드맵 · 편성 · 연무장/보물/내정 준비 중 · 동맹 추후) · 재화 바(월드맵 포함 · 군량 타이머) · 하단 탭 5 · ◀/Esc 일관 · 영웅 목록·상세·상세정보·도감 · 편성(탭·드래그) · 뽑기(천장 n/80 · 확률 공개 · 첫 10연 무료 · 10연 ★★ 보장 · 카드 순차 공개) · 장비 상점(흰/녹 6종 일일 · sell×5 · 새로고침 보옥 20) - 전투 연결: BattleManager.LineupProvider/Deployed(LineupEntry · §3-2 스탯 · 방어 배율 생성 뒤) · playerSpawnPoints = 전열 (−4/0/4, −12) · 후열 (−2/2, −14) · WorldMapScreen 훅(팝업 군량·보상·별 · 입장 군량 · 노드 별 star_on/off · 소탕 · ◀ 본영 · TopInset) · 결과 패널(별 3 조건 · 골드·경험·보옥·장비) · GameBootstrap/AutoPlayDriver 로비 시작 - B 세션 파일(ActionResolver·Combat·UnitView·BattleHUD·SlingshotInput·EnemyAI) 미변경 - 테스트 56/56(기존 41 유지 · 신규 OutGameTests 15) · console error 0 · 사본 GUI 캡처 11장(DataImporter.CaptureOutGame) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:11:10 +00:00
Button popupSweep;
Text popupSweepLabel;
전투 결과 · 공용 팝업 · 거래 비주얼 개선 = Fable 제안서 §4-2~§4-4 구현(#1104 · PD 2026-11-09) - 전투 결과: 별 받침 원 + 큰 별(Icon_Star_On/Off 한 벌) 0.15 s 튀김(UiPop) · 조건 행 3(체크/엑스) · 보상 타일(ItemFrame 5층 + 수량 칩 · 장비 = 등급 칸 · 상자) · 「다시」(같은 노드 재출전 · 군량 확인 · WorldMapScreen.RetryLast · 화면 탭은 이 버튼 위만 제외 = SlingshotInput.HoldResultTap) + 「확인」 Primary 노랑 · 리본 뒤 금빛(호흡) - 군량 팝업: 필드 인셋 · 현재 군량 블록 · 교환 행 2(비용 → 군량 · 오늘 횟수 · Secondary 하늘/녹 · 다 쓰면 회색) · 닫기 = X 만 - 스테이지 팝업: 필드 인셋 · 적 구성 병종 원 ×n + 장수 칩 · 보상 타일 4(첫 클리어 뱃지) · 별 조건 행 3 · 출정 = 붉은 Primary + 군량 비용 · 소탕 = 녹 Secondary · 닫기 버튼 삭제(PopupFill · CostOf 훅) - 거래(뽑기): 목록 바탕 · 서브탭 Round10 · 배너 아래 문양 띠 + 「픽업」 뱃지 · 천장 = 레벨형 게이지 + 노랑 배지 · 확률 = 섹션 패널 + 제목 띠 + 행 3(별 · 바 · %) · 1회 Secondary 하늘 + 보옥 비용 · 10연 Primary 노랑 + 「첫 무료」 꼬리 칩 · 각주 → ⓘ 팝업 - UiKit 공용 부품 ②: At · SkinBtn · BtnCost · SubTab/SetSubTab · Gauge/SetGauge · InfoChip · QtyChip · RewardTile · CondRow · SubTitle - 테마 행 추가(ui_theme.csv): 버튼 btn_l_yellow·btn_l_red · 소제목 선 · 큰 별 · 뱃지 · 배너 문양 · 상자 색(구 TreasureScreen.ChestColor 상수 이관 준비) 등 - 테스트 117/117 · console error 0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 09:03:43 +00:00
RectTransform popupField;
Text popupCost;
Text popupCode;
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
int popupNode = -1;
아웃게임 1차(PD #1093 세션 A) — 본영 로비 · 세이브 · 군량 · 영웅(레벨·승급 6칸·진화·스킬 표시) · 편성(전열 3/후열 2 · 프리셋 3) · 거래(뽑기·골드 장비 상점) · 스테이지 보상·별 3·소탕 - 데이터: 기획 tables/ 12장 → Assets/Data/OutGame/*.csv · 메뉴 TKS/Import OutGame Data(Editor/DataImporter) → Resources/OutGame 9 자산(HeroDb·GearDb·GachaConfig·EconomyConfig·RewardTable·LevelTable·PromotionTable·EvolveTable·SkillInfoDb) · 검증(행 수·필수 열·id 유일·hero↔skill↔gear·확률 합) 오류 시 자산 불변 · BalanceConfig.heroes[]/HeroDef 삭제 → HeroDb(기존 5인 id 유지) · economy.csv 키 17 + gacha.csv 키 2 추가(기획서 본문 값 · C45) - 세이브: persistentDataPath/save.json · ver 1 · 즉시 저장 · 오프라인 군량 회복 · 일일 초기화 · 신규 유저 = 유비·관우·장비·조운·황충 Lv1 녹 ★=희귀도 · 골드 1000 · 보옥 300 · 군량 30 · 테스트·캡처 = 메모리 전용 - 화면(uGUI 와이어프레임 · img03·06·08·11): 시작 = 본영 로비(출정 → 월드맵 · 편성 · 연무장/보물/내정 준비 중 · 동맹 추후) · 재화 바(월드맵 포함 · 군량 타이머) · 하단 탭 5 · ◀/Esc 일관 · 영웅 목록·상세·상세정보·도감 · 편성(탭·드래그) · 뽑기(천장 n/80 · 확률 공개 · 첫 10연 무료 · 10연 ★★ 보장 · 카드 순차 공개) · 장비 상점(흰/녹 6종 일일 · sell×5 · 새로고침 보옥 20) - 전투 연결: BattleManager.LineupProvider/Deployed(LineupEntry · §3-2 스탯 · 방어 배율 생성 뒤) · playerSpawnPoints = 전열 (−4/0/4, −12) · 후열 (−2/2, −14) · WorldMapScreen 훅(팝업 군량·보상·별 · 입장 군량 · 노드 별 star_on/off · 소탕 · ◀ 본영 · TopInset) · 결과 패널(별 3 조건 · 골드·경험·보옥·장비) · GameBootstrap/AutoPlayDriver 로비 시작 - B 세션 파일(ActionResolver·Combat·UnitView·BattleHUD·SlingshotInput·EnemyAI) 미변경 - 테스트 56/56(기존 41 유지 · 신규 OutGameTests 15) · console error 0 · 사본 GUI 캡처 11장(DataImporter.CaptureOutGame) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:11:10 +00:00
RectTransform bannerRt;
RectTransform prevRt;
RectTransform nextRt;
Button backButton;
// ---------- 아웃게임 연결(2026-11-05 #1093 · OutGame/OutGameRoot 가 채움 · 비면 기존 동작) ----------
/// <summary>스테이지 인덱스 → 팝업 추가 줄(군량 · 보상 · 별).</summary>
public Func<int, string> PopupInfo;
전투 결과 · 공용 팝업 · 거래 비주얼 개선 = Fable 제안서 §4-2~§4-4 구현(#1104 · PD 2026-11-09) - 전투 결과: 별 받침 원 + 큰 별(Icon_Star_On/Off 한 벌) 0.15 s 튀김(UiPop) · 조건 행 3(체크/엑스) · 보상 타일(ItemFrame 5층 + 수량 칩 · 장비 = 등급 칸 · 상자) · 「다시」(같은 노드 재출전 · 군량 확인 · WorldMapScreen.RetryLast · 화면 탭은 이 버튼 위만 제외 = SlingshotInput.HoldResultTap) + 「확인」 Primary 노랑 · 리본 뒤 금빛(호흡) - 군량 팝업: 필드 인셋 · 현재 군량 블록 · 교환 행 2(비용 → 군량 · 오늘 횟수 · Secondary 하늘/녹 · 다 쓰면 회색) · 닫기 = X 만 - 스테이지 팝업: 필드 인셋 · 적 구성 병종 원 ×n + 장수 칩 · 보상 타일 4(첫 클리어 뱃지) · 별 조건 행 3 · 출정 = 붉은 Primary + 군량 비용 · 소탕 = 녹 Secondary · 닫기 버튼 삭제(PopupFill · CostOf 훅) - 거래(뽑기): 목록 바탕 · 서브탭 Round10 · 배너 아래 문양 띠 + 「픽업」 뱃지 · 천장 = 레벨형 게이지 + 노랑 배지 · 확률 = 섹션 패널 + 제목 띠 + 행 3(별 · 바 · %) · 1회 Secondary 하늘 + 보옥 비용 · 10연 Primary 노랑 + 「첫 무료」 꼬리 칩 · 각주 → ⓘ 팝업 - UiKit 공용 부품 ②: At · SkinBtn · BtnCost · SubTab/SetSubTab · Gauge/SetGauge · InfoChip · QtyChip · RewardTile · CondRow · SubTitle - 테마 행 추가(ui_theme.csv): 버튼 btn_l_yellow·btn_l_red · 소제목 선 · 큰 별 · 뱃지 · 배너 문양 · 상자 색(구 TreasureScreen.ChestColor 상수 이관 준비) 등 - 테스트 117/117 · console error 0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 09:03:43 +00:00
/// <summary>스테이지 팝업 본문 그리기(스테이지 인덱스 · 잠김 · 필드) — 있으면 글자 본문 대신(Fable 제안서 §4-3 · #1104).</summary>
public Action<int, bool, RectTransform> PopupFill;
/// <summary>출전 군량(스테이지 인덱스) — 출정 버튼 비용 칩.</summary>
public Func<int, int> CostOf;
아웃게임 1차(PD #1093 세션 A) — 본영 로비 · 세이브 · 군량 · 영웅(레벨·승급 6칸·진화·스킬 표시) · 편성(전열 3/후열 2 · 프리셋 3) · 거래(뽑기·골드 장비 상점) · 스테이지 보상·별 3·소탕 - 데이터: 기획 tables/ 12장 → Assets/Data/OutGame/*.csv · 메뉴 TKS/Import OutGame Data(Editor/DataImporter) → Resources/OutGame 9 자산(HeroDb·GearDb·GachaConfig·EconomyConfig·RewardTable·LevelTable·PromotionTable·EvolveTable·SkillInfoDb) · 검증(행 수·필수 열·id 유일·hero↔skill↔gear·확률 합) 오류 시 자산 불변 · BalanceConfig.heroes[]/HeroDef 삭제 → HeroDb(기존 5인 id 유지) · economy.csv 키 17 + gacha.csv 키 2 추가(기획서 본문 값 · C45) - 세이브: persistentDataPath/save.json · ver 1 · 즉시 저장 · 오프라인 군량 회복 · 일일 초기화 · 신규 유저 = 유비·관우·장비·조운·황충 Lv1 녹 ★=희귀도 · 골드 1000 · 보옥 300 · 군량 30 · 테스트·캡처 = 메모리 전용 - 화면(uGUI 와이어프레임 · img03·06·08·11): 시작 = 본영 로비(출정 → 월드맵 · 편성 · 연무장/보물/내정 준비 중 · 동맹 추후) · 재화 바(월드맵 포함 · 군량 타이머) · 하단 탭 5 · ◀/Esc 일관 · 영웅 목록·상세·상세정보·도감 · 편성(탭·드래그) · 뽑기(천장 n/80 · 확률 공개 · 첫 10연 무료 · 10연 ★★ 보장 · 카드 순차 공개) · 장비 상점(흰/녹 6종 일일 · sell×5 · 새로고침 보옥 20) - 전투 연결: BattleManager.LineupProvider/Deployed(LineupEntry · §3-2 스탯 · 방어 배율 생성 뒤) · playerSpawnPoints = 전열 (−4/0/4, −12) · 후열 (−2/2, −14) · WorldMapScreen 훅(팝업 군량·보상·별 · 입장 군량 · 노드 별 star_on/off · 소탕 · ◀ 본영 · TopInset) · 결과 패널(별 3 조건 · 골드·경험·보옥·장비) · GameBootstrap/AutoPlayDriver 로비 시작 - B 세션 파일(ActionResolver·Combat·UnitView·BattleHUD·SlingshotInput·EnemyAI) 미변경 - 테스트 56/56(기존 41 유지 · 신규 OutGameTests 15) · console error 0 · 사본 GUI 캡처 11장(DataImporter.CaptureOutGame) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:11:10 +00:00
/// <summary>출전 직전(군량 지불) · false = 출전 안 함(부족 안내는 연결한 쪽이 띄움).</summary>
public Func<int, bool> TryEnter;
/// <summary>깬 노드 별 수(0~3) · null 이면 깬 노드 = 별 전부.</summary>
public Func<int, int> StarsOf;
/// <summary>소탕(별 3 · 전투 없음) 가능 여부 · 실행.</summary>
public Func<int, bool> CanSweep;
public Action<int> Sweep;
/// <summary>「◀ 본영」(로비로) · null 이면 버튼 숨김.</summary>
public Action BackRequested;
/// <summary>위 공통 재화 바 높이(UI px) — 챕터 띠·넘김 버튼을 그만큼 내린다.</summary>
public float TopInset;
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
float inputBlockUntil;
int chapter;
int entryChapter = -1;
int entryNode = -1;
public bool HasData
{
get { return data != null && data.chapters != null && data.chapters.Length > 0 && cfg != null && cfg.chapters != null && cfg.chapters.Length > 0 && cfg.stages.Length > 0; }
}
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
public bool IsVisible { get { return root != null && root.activeSelf; } }
public bool PopupVisible { get { return popup != null && popup.activeSelf; } }
public int Chapter { get { return chapter; } }
public int ChapterCount { get { return HasData ? cfg.chapters.Length : 0; } }
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
public WorldData Data { get { return data; } }
public Sprite MapSprite { get { return mapImage != null ? mapImage.sprite : null; } }
public int NodeCount { get { return nodeButtons.Count; } }
public int BossNodeCount { get; private set; }
/// <summary>챕터(0부터)의 노드 수 = 스테이지 표의 그 챕터 스테이지 수.</summary>
public int NodesIn(int ch)
{
return HasData && ch >= 0 && ch < cfg.chapters.Length ? cfg.StagesOfChapter(cfg.chapters[ch].no).Count : 0;
}
/// <summary>챕터(0부터) · 노드(0부터) → BalanceConfig.stages 인덱스(없으면 −1).</summary>
public int StageIndexOf(int ch, int node)
{
if (!HasData || ch < 0 || ch >= cfg.chapters.Length) return -1;
var list = cfg.StagesOfChapter(cfg.chapters[ch].no);
return node >= 0 && node < list.Count ? list[node] : -1;
}
/// <summary>챕터(0부터)의 맵 길(world.json · chapters.csv map 열). 없으면 첫 맵.</summary>
public WorldChapter MapOf(int ch)
{
if (!HasData) return null;
var wc = ch >= 0 && ch < cfg.chapters.Length ? data.FindMap(cfg.chapters[ch].map) : null;
return wc ?? data.chapters[0];
}
/// <summary>
/// 노드 자리(맵 px) = Data/&lt;맵&gt;.json stages[].at(스테이지 번호로 맞춤 · 기획 확정판 맵) → 없거나 번호가 빠지면 slots_N → 그것도 없으면 길 위 균등.
/// </summary>
public Vector2[] NodeSlots(int ch, out NodeSource source)
{
var list = HasData && ch >= 0 && ch < cfg.chapters.Length ? cfg.StagesOfChapter(cfg.chapters[ch].no) : new List<int>();
int n = list.Count;
var wc = MapOf(ch);
var plan = wc != null ? WorldData.AnchorStages(wc.map) : null;
if (plan != null)
{
var res = new Vector2[n];
int found = 0;
for (int i = 0; i < n; i++)
foreach (var p in plan)
if (p.stage == cfg.stages[list[i]].stage && p.at != null && p.at.Length >= 2)
{
res[i] = new Vector2(p.at[0], p.at[1]);
found++;
break;
}
if (found == n)
{
source = NodeSource.Stages;
return res;
}
Debug.LogWarning("[TKS] " + wc.map + " stages[].at 이 스테이지 표와 안 맞음(" + found + "/" + n + ") → slots_N");
}
var s = wc != null ? WorldData.AnchorSlots(wc.map, n) : null;
source = s != null ? NodeSource.Slots : NodeSource.Road;
return s ?? (wc != null ? WorldData.Slots(wc, n) : new Vector2[0]);
}
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
void Awake()
{
Instance = this;
}
void OnDestroy()
{
if (Instance == this) Instance = null;
}
public void Build(BattleManager b, BattleHUD h, SlingshotInput s, Camera cam)
{
battle = b;
hud = h;
sling = s;
data = WorldData.Load();
cfg = b != null ? b.Config : null;
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
if (!HasData)
{
Debug.LogWarning("[TKS] 월드맵 데이터 없음(" + WorldData.Path + " 또는 BalanceConfig.chapters — TKS/Import Stages) → 바로 전투");
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
return;
}
battle.ResultHandler = OnBattleResult;
// 캔버스 층(PD 2026-11-10): 루트 = 바탕 · 챕터 띠 · 넘김 · 본영 버튼(챕터를 바꿀 때만 · Static)
// → Content(맵 · 노드 · 스크롤로 움직임 · Frame) → 커서(매 프레임 흔들림 · Frame) · Popup(Event)
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
root = new GameObject("WorldMapCanvas");
root.transform.SetParent(transform, false);
UiLayer.Root(root, cam, 300, 0.5f, new Vector2(data.viewSize[0], data.viewSize[1]), UiRate.Static); // 카메라 캡처(자동 플레이)에도 찍힘
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
group = root.AddComponent<CanvasGroup>();
// 스크롤(맵 = 콘텐츠 · 왼쪽 위 기준)
viewport = Rect("Viewport", root.transform, Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f), Vector2.zero, Vector2.zero);
var vpImg = viewport.gameObject.AddComponent<Image>();
vpImg.color = new Color(0.1f, 0.12f, 0.1f);
viewport.gameObject.AddComponent<RectMask2D>();
content = Rect("Content", viewport, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(0f, 1f), Vector2.zero, new Vector2(data.mapSize[0], data.mapSize[1]));
UiLayer.Nest(content.gameObject, UiRate.Frame, true); // 스크롤 내용 = 자기 캔버스(노드 = 누름)
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
mapImage = content.gameObject.AddComponent<Image>();
mapImage.raycastTarget = true; // 맵 아무 데나 끌기
scroll = viewport.gameObject.AddComponent<ScrollRect>();
scroll.viewport = viewport;
scroll.content = content;
scroll.horizontal = true;
scroll.vertical = true;
scroll.movementType = ScrollRect.MovementType.Clamped;
scroll.inertia = true;
scroll.decelerationRate = 0.12f;
scroll.scrollSensitivity = 60f;
// 위 챕터 띠 + 챕터 넘김
var banner = Img("Banner", root.transform, Sprite("banner"), new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -40f), new Vector2(640f, 112f));
banner.type = Image.Type.Sliced;
var bk = data.Kit("banner");
float tcy = bk != null && bk.numberCenter != null ? bk.numberCenter[1] : 0.4f;
bannerText = Label(banner.transform, "", 40, Paper, new Vector2(0.5f, 1f - tcy));
아웃게임 1차(PD #1093 세션 A) — 본영 로비 · 세이브 · 군량 · 영웅(레벨·승급 6칸·진화·스킬 표시) · 편성(전열 3/후열 2 · 프리셋 3) · 거래(뽑기·골드 장비 상점) · 스테이지 보상·별 3·소탕 - 데이터: 기획 tables/ 12장 → Assets/Data/OutGame/*.csv · 메뉴 TKS/Import OutGame Data(Editor/DataImporter) → Resources/OutGame 9 자산(HeroDb·GearDb·GachaConfig·EconomyConfig·RewardTable·LevelTable·PromotionTable·EvolveTable·SkillInfoDb) · 검증(행 수·필수 열·id 유일·hero↔skill↔gear·확률 합) 오류 시 자산 불변 · BalanceConfig.heroes[]/HeroDef 삭제 → HeroDb(기존 5인 id 유지) · economy.csv 키 17 + gacha.csv 키 2 추가(기획서 본문 값 · C45) - 세이브: persistentDataPath/save.json · ver 1 · 즉시 저장 · 오프라인 군량 회복 · 일일 초기화 · 신규 유저 = 유비·관우·장비·조운·황충 Lv1 녹 ★=희귀도 · 골드 1000 · 보옥 300 · 군량 30 · 테스트·캡처 = 메모리 전용 - 화면(uGUI 와이어프레임 · img03·06·08·11): 시작 = 본영 로비(출정 → 월드맵 · 편성 · 연무장/보물/내정 준비 중 · 동맹 추후) · 재화 바(월드맵 포함 · 군량 타이머) · 하단 탭 5 · ◀/Esc 일관 · 영웅 목록·상세·상세정보·도감 · 편성(탭·드래그) · 뽑기(천장 n/80 · 확률 공개 · 첫 10연 무료 · 10연 ★★ 보장 · 카드 순차 공개) · 장비 상점(흰/녹 6종 일일 · sell×5 · 새로고침 보옥 20) - 전투 연결: BattleManager.LineupProvider/Deployed(LineupEntry · §3-2 스탯 · 방어 배율 생성 뒤) · playerSpawnPoints = 전열 (−4/0/4, −12) · 후열 (−2/2, −14) · WorldMapScreen 훅(팝업 군량·보상·별 · 입장 군량 · 노드 별 star_on/off · 소탕 · ◀ 본영 · TopInset) · 결과 패널(별 3 조건 · 골드·경험·보옥·장비) · GameBootstrap/AutoPlayDriver 로비 시작 - B 세션 파일(ActionResolver·Combat·UnitView·BattleHUD·SlingshotInput·EnemyAI) 미변경 - 테스트 56/56(기존 41 유지 · 신규 OutGameTests 15) · console error 0 · 사본 GUI 캡처 11장(DataImporter.CaptureOutGame) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:11:10 +00:00
bannerRt = banner.rectTransform;
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
prevButton = SmallButton("Prev", root.transform, "◀", new Vector2(0f, 1f), new Vector2(70f, -96f), () => ShowChapter(chapter - 1));
nextButton = SmallButton("Next", root.transform, "▶", new Vector2(1f, 1f), new Vector2(-70f, -96f), () => ShowChapter(chapter + 1));
아웃게임 1차(PD #1093 세션 A) — 본영 로비 · 세이브 · 군량 · 영웅(레벨·승급 6칸·진화·스킬 표시) · 편성(전열 3/후열 2 · 프리셋 3) · 거래(뽑기·골드 장비 상점) · 스테이지 보상·별 3·소탕 - 데이터: 기획 tables/ 12장 → Assets/Data/OutGame/*.csv · 메뉴 TKS/Import OutGame Data(Editor/DataImporter) → Resources/OutGame 9 자산(HeroDb·GearDb·GachaConfig·EconomyConfig·RewardTable·LevelTable·PromotionTable·EvolveTable·SkillInfoDb) · 검증(행 수·필수 열·id 유일·hero↔skill↔gear·확률 합) 오류 시 자산 불변 · BalanceConfig.heroes[]/HeroDef 삭제 → HeroDb(기존 5인 id 유지) · economy.csv 키 17 + gacha.csv 키 2 추가(기획서 본문 값 · C45) - 세이브: persistentDataPath/save.json · ver 1 · 즉시 저장 · 오프라인 군량 회복 · 일일 초기화 · 신규 유저 = 유비·관우·장비·조운·황충 Lv1 녹 ★=희귀도 · 골드 1000 · 보옥 300 · 군량 30 · 테스트·캡처 = 메모리 전용 - 화면(uGUI 와이어프레임 · img03·06·08·11): 시작 = 본영 로비(출정 → 월드맵 · 편성 · 연무장/보물/내정 준비 중 · 동맹 추후) · 재화 바(월드맵 포함 · 군량 타이머) · 하단 탭 5 · ◀/Esc 일관 · 영웅 목록·상세·상세정보·도감 · 편성(탭·드래그) · 뽑기(천장 n/80 · 확률 공개 · 첫 10연 무료 · 10연 ★★ 보장 · 카드 순차 공개) · 장비 상점(흰/녹 6종 일일 · sell×5 · 새로고침 보옥 20) - 전투 연결: BattleManager.LineupProvider/Deployed(LineupEntry · §3-2 스탯 · 방어 배율 생성 뒤) · playerSpawnPoints = 전열 (−4/0/4, −12) · 후열 (−2/2, −14) · WorldMapScreen 훅(팝업 군량·보상·별 · 입장 군량 · 노드 별 star_on/off · 소탕 · ◀ 본영 · TopInset) · 결과 패널(별 3 조건 · 골드·경험·보옥·장비) · GameBootstrap/AutoPlayDriver 로비 시작 - B 세션 파일(ActionResolver·Combat·UnitView·BattleHUD·SlingshotInput·EnemyAI) 미변경 - 테스트 56/56(기존 41 유지 · 신규 OutGameTests 15) · console error 0 · 사본 GUI 캡처 11장(DataImporter.CaptureOutGame) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:11:10 +00:00
prevRt = (RectTransform)prevButton.transform;
nextRt = (RectTransform)nextButton.transform;
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
var hint = Label(root.transform, "맵을 끌어 둘러보고 깃발을 눌러 출전", 30, Paper, new Vector2(0.5f, 0f));
var hrt = hint.rectTransform;
hrt.anchorMin = hrt.anchorMax = new Vector2(0.5f, 0f);
hrt.anchoredPosition = new Vector2(0f, 90f);
아웃게임 1차(PD #1093 세션 A) — 본영 로비 · 세이브 · 군량 · 영웅(레벨·승급 6칸·진화·스킬 표시) · 편성(전열 3/후열 2 · 프리셋 3) · 거래(뽑기·골드 장비 상점) · 스테이지 보상·별 3·소탕 - 데이터: 기획 tables/ 12장 → Assets/Data/OutGame/*.csv · 메뉴 TKS/Import OutGame Data(Editor/DataImporter) → Resources/OutGame 9 자산(HeroDb·GearDb·GachaConfig·EconomyConfig·RewardTable·LevelTable·PromotionTable·EvolveTable·SkillInfoDb) · 검증(행 수·필수 열·id 유일·hero↔skill↔gear·확률 합) 오류 시 자산 불변 · BalanceConfig.heroes[]/HeroDef 삭제 → HeroDb(기존 5인 id 유지) · economy.csv 키 17 + gacha.csv 키 2 추가(기획서 본문 값 · C45) - 세이브: persistentDataPath/save.json · ver 1 · 즉시 저장 · 오프라인 군량 회복 · 일일 초기화 · 신규 유저 = 유비·관우·장비·조운·황충 Lv1 녹 ★=희귀도 · 골드 1000 · 보옥 300 · 군량 30 · 테스트·캡처 = 메모리 전용 - 화면(uGUI 와이어프레임 · img03·06·08·11): 시작 = 본영 로비(출정 → 월드맵 · 편성 · 연무장/보물/내정 준비 중 · 동맹 추후) · 재화 바(월드맵 포함 · 군량 타이머) · 하단 탭 5 · ◀/Esc 일관 · 영웅 목록·상세·상세정보·도감 · 편성(탭·드래그) · 뽑기(천장 n/80 · 확률 공개 · 첫 10연 무료 · 10연 ★★ 보장 · 카드 순차 공개) · 장비 상점(흰/녹 6종 일일 · sell×5 · 새로고침 보옥 20) - 전투 연결: BattleManager.LineupProvider/Deployed(LineupEntry · §3-2 스탯 · 방어 배율 생성 뒤) · playerSpawnPoints = 전열 (−4/0/4, −12) · 후열 (−2/2, −14) · WorldMapScreen 훅(팝업 군량·보상·별 · 입장 군량 · 노드 별 star_on/off · 소탕 · ◀ 본영 · TopInset) · 결과 패널(별 3 조건 · 골드·경험·보옥·장비) · GameBootstrap/AutoPlayDriver 로비 시작 - B 세션 파일(ActionResolver·Combat·UnitView·BattleHUD·SlingshotInput·EnemyAI) 미변경 - 테스트 56/56(기존 41 유지 · 신규 OutGameTests 15) · console error 0 · 사본 GUI 캡처 11장(DataImporter.CaptureOutGame) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:11:10 +00:00
// 본영(로비)으로 — 아웃게임이 BackRequested 를 채우면 보인다
var back = Img("Back", root.transform, Sprite("plate"), new Vector2(0f, 0f), new Vector2(0f, 0f), new Vector2(0.5f, 0.5f), new Vector2(130f, 90f), new Vector2(220f, 96f));
back.type = Image.Type.Sliced;
back.raycastTarget = true;
backButton = back.gameObject.AddComponent<Button>();
backButton.onClick.AddListener(() =>
{
if (BackRequested != null && Time.unscaledTime >= inputBlockUntil) BackRequested();
});
var bl = Label(back.transform, "◀ 본영", 36, new Color(0.45f, 0.22f, 0.12f), new Vector2(0.5f, 0.55f));
bl.GetComponent<Outline>().enabled = false;
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
BuildPopup();
root.SetActive(false);
}
// ---------- 화면 전환 ----------
/// <summary>월드맵을 연다(전투 정리 · 전투 HUD·조작 끔).</summary>
public void Show(int ch)
{
if (!HasData) return;
if (battle != null && battle.Phase != BattlePhase.Setup) battle.GoIdle();
if (hud != null) hud.gameObject.SetActive(false);
if (sling != null) sling.enabled = false;
root.SetActive(true);
inputBlockUntil = Time.unscaledTime + 0.25f; // 결과 화면 탭이 노드 클릭으로 이어지지 않게
아웃게임 1차(PD #1093 세션 A) — 본영 로비 · 세이브 · 군량 · 영웅(레벨·승급 6칸·진화·스킬 표시) · 편성(전열 3/후열 2 · 프리셋 3) · 거래(뽑기·골드 장비 상점) · 스테이지 보상·별 3·소탕 - 데이터: 기획 tables/ 12장 → Assets/Data/OutGame/*.csv · 메뉴 TKS/Import OutGame Data(Editor/DataImporter) → Resources/OutGame 9 자산(HeroDb·GearDb·GachaConfig·EconomyConfig·RewardTable·LevelTable·PromotionTable·EvolveTable·SkillInfoDb) · 검증(행 수·필수 열·id 유일·hero↔skill↔gear·확률 합) 오류 시 자산 불변 · BalanceConfig.heroes[]/HeroDef 삭제 → HeroDb(기존 5인 id 유지) · economy.csv 키 17 + gacha.csv 키 2 추가(기획서 본문 값 · C45) - 세이브: persistentDataPath/save.json · ver 1 · 즉시 저장 · 오프라인 군량 회복 · 일일 초기화 · 신규 유저 = 유비·관우·장비·조운·황충 Lv1 녹 ★=희귀도 · 골드 1000 · 보옥 300 · 군량 30 · 테스트·캡처 = 메모리 전용 - 화면(uGUI 와이어프레임 · img03·06·08·11): 시작 = 본영 로비(출정 → 월드맵 · 편성 · 연무장/보물/내정 준비 중 · 동맹 추후) · 재화 바(월드맵 포함 · 군량 타이머) · 하단 탭 5 · ◀/Esc 일관 · 영웅 목록·상세·상세정보·도감 · 편성(탭·드래그) · 뽑기(천장 n/80 · 확률 공개 · 첫 10연 무료 · 10연 ★★ 보장 · 카드 순차 공개) · 장비 상점(흰/녹 6종 일일 · sell×5 · 새로고침 보옥 20) - 전투 연결: BattleManager.LineupProvider/Deployed(LineupEntry · §3-2 스탯 · 방어 배율 생성 뒤) · playerSpawnPoints = 전열 (−4/0/4, −12) · 후열 (−2/2, −14) · WorldMapScreen 훅(팝업 군량·보상·별 · 입장 군량 · 노드 별 star_on/off · 소탕 · ◀ 본영 · TopInset) · 결과 패널(별 3 조건 · 골드·경험·보옥·장비) · GameBootstrap/AutoPlayDriver 로비 시작 - B 세션 파일(ActionResolver·Combat·UnitView·BattleHUD·SlingshotInput·EnemyAI) 미변경 - 테스트 56/56(기존 41 유지 · 신규 OutGameTests 15) · console error 0 · 사본 GUI 캡처 11장(DataImporter.CaptureOutGame) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:11:10 +00:00
bannerRt.anchoredPosition = new Vector2(0f, -40f - TopInset);
prevRt.anchoredPosition = new Vector2(70f, -96f - TopInset);
nextRt.anchoredPosition = new Vector2(-70f, -96f - TopInset);
backButton.gameObject.SetActive(BackRequested != null);
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
ShowChapter(ch);
}
아웃게임 1차(PD #1093 세션 A) — 본영 로비 · 세이브 · 군량 · 영웅(레벨·승급 6칸·진화·스킬 표시) · 편성(전열 3/후열 2 · 프리셋 3) · 거래(뽑기·골드 장비 상점) · 스테이지 보상·별 3·소탕 - 데이터: 기획 tables/ 12장 → Assets/Data/OutGame/*.csv · 메뉴 TKS/Import OutGame Data(Editor/DataImporter) → Resources/OutGame 9 자산(HeroDb·GearDb·GachaConfig·EconomyConfig·RewardTable·LevelTable·PromotionTable·EvolveTable·SkillInfoDb) · 검증(행 수·필수 열·id 유일·hero↔skill↔gear·확률 합) 오류 시 자산 불변 · BalanceConfig.heroes[]/HeroDef 삭제 → HeroDb(기존 5인 id 유지) · economy.csv 키 17 + gacha.csv 키 2 추가(기획서 본문 값 · C45) - 세이브: persistentDataPath/save.json · ver 1 · 즉시 저장 · 오프라인 군량 회복 · 일일 초기화 · 신규 유저 = 유비·관우·장비·조운·황충 Lv1 녹 ★=희귀도 · 골드 1000 · 보옥 300 · 군량 30 · 테스트·캡처 = 메모리 전용 - 화면(uGUI 와이어프레임 · img03·06·08·11): 시작 = 본영 로비(출정 → 월드맵 · 편성 · 연무장/보물/내정 준비 중 · 동맹 추후) · 재화 바(월드맵 포함 · 군량 타이머) · 하단 탭 5 · ◀/Esc 일관 · 영웅 목록·상세·상세정보·도감 · 편성(탭·드래그) · 뽑기(천장 n/80 · 확률 공개 · 첫 10연 무료 · 10연 ★★ 보장 · 카드 순차 공개) · 장비 상점(흰/녹 6종 일일 · sell×5 · 새로고침 보옥 20) - 전투 연결: BattleManager.LineupProvider/Deployed(LineupEntry · §3-2 스탯 · 방어 배율 생성 뒤) · playerSpawnPoints = 전열 (−4/0/4, −12) · 후열 (−2/2, −14) · WorldMapScreen 훅(팝업 군량·보상·별 · 입장 군량 · 노드 별 star_on/off · 소탕 · ◀ 본영 · TopInset) · 결과 패널(별 3 조건 · 골드·경험·보옥·장비) · GameBootstrap/AutoPlayDriver 로비 시작 - B 세션 파일(ActionResolver·Combat·UnitView·BattleHUD·SlingshotInput·EnemyAI) 미변경 - 테스트 56/56(기존 41 유지 · 신규 OutGameTests 15) · console error 0 · 사본 GUI 캡처 11장(DataImporter.CaptureOutGame) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:11:10 +00:00
/// <summary>월드맵을 닫는다(로비로 돌아갈 때 · 전투는 건드리지 않음).</summary>
public void Hide()
{
ClosePopup();
if (root != null) root.SetActive(false);
}
/// <summary>팝업이 열려 있으면 내용을 다시 채운다(군량 구매·소탕 뒤).</summary>
public void RefreshPopup()
{
if (PopupVisible && popupNode >= 0) OpenPopup(popupNode);
}
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
public void ShowChapter(int ch)
{
if (!HasData) return;
chapter = Mathf.Clamp(ch, 0, cfg.chapters.Length - 1);
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
ClosePopup();
var def = cfg.chapters[chapter];
var c = MapOf(chapter);
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
foreach (var go in spawned)
if (go != null) Destroy(go);
spawned.Clear();
nodeButtons.Clear();
cursor = null;
nodeStages.Clear();
nodeStages.AddRange(cfg.StagesOfChapter(def.no));
BossNodeCount = 0;
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
if (c.map != def.map) Debug.LogWarning("[TKS] 챕터 " + def.no + " 맵 「" + def.map + "」 이 world.json 에 없음 → " + c.map);
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
var sp = Resources.Load<Sprite>(MapRoot + c.map);
if (sp == null) Debug.LogWarning("[TKS] 맵 그림 없음: " + MapRoot + c.map);
mapImage.sprite = sp;
mapImage.color = sp != null ? Color.white : new Color(0.55f, 0.7f, 0.45f);
bannerText.text = "제" + def.no + "장 " + def.title;
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
prevButton.interactable = chapter > 0;
nextButton.interactable = chapter < cfg.chapters.Length - 1;
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
NodeSource source;
var slots = NodeSlots(chapter, out source);
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
var acc = WorldData.Arc(c);
var len = new float[slots.Length];
for (int i = 0; i < slots.Length; i++) len[i] = WorldData.ArcOf(c, acc, slots[i]);
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
int cleared = ChapterUnlocked(chapter) ? WorldProgress.Cleared(chapter) : 0;
// 길 점(노드 사이 · 노드 자리를 길에 투영한 호 길이 구간)
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
float spacing = Mathf.Max(8f, data.dotSpacing);
for (int i = 0; i + 1 < slots.Length; i++)
{
float l0 = Mathf.Min(len[i], len[i + 1]) + 44f;
float l1 = Mathf.Max(len[i], len[i + 1]) - 44f;
if (l1 <= l0) continue;
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
int m = Mathf.Max(0, Mathf.FloorToInt((l1 - l0) / spacing));
for (int j = 0; j <= m; j++)
{
var p = WorldData.At(c, acc, Mathf.Lerp(l0, l1, m == 0 ? 0.5f : (float)j / m));
Piece(i < cleared ? "dot_on" : "dot_off", p, false);
}
}
// 장소 이름판
if (data.showLabels && c.landmarks != null)
foreach (var L in c.landmarks)
{
if (string.IsNullOrEmpty(L.ko)) continue;
var plate = Piece("plate", new Vector2(L.x, L.y), false);
if (plate == null) continue;
plate.type = Image.Type.Sliced;
var t = Label(plate.transform, L.ko, 26, new Color(0.28f, 0.17f, 0.11f), new Vector2(0.5f, 0.5f));
t.GetComponent<Outline>().enabled = false;
plate.rectTransform.sizeDelta = new Vector2(t.preferredWidth + 60f, plate.rectTransform.sizeDelta.y);
}
// 노드
for (int i = 0; i < slots.Length; i++)
{
var stage = cfg.stages[nodeStages[i]];
bool boss = stage.kind == StageKind.Boss;
if (boss) BossNodeCount++;
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
var st = StateOf(chapter, i);
string key = (boss ? "flag_boss_" : "flag_") + (st == NodeState.Clear ? "clear" : st == NodeState.Open ? "open" : "lock");
if (boss) Piece("frame", slots[i] + V(data.flagFrame), false);
var img = Piece(key, slots[i], true);
if (img == null) continue;
int node = i;
var btn = img.gameObject.AddComponent<Button>();
btn.transition = Selectable.Transition.ColorTint;
btn.onClick.AddListener(() => OnNodeClicked(node));
nodeButtons.Add(btn);
var kit = data.Kit(key);
if (st != NodeState.Lock && kit != null)
{
var t = Label(img.transform, def.no + "-" + stage.stage, boss ? 38 : (def.no >= 10 || stage.stage >= 10 ? 26 : 32), Paper, new Vector2(kit.numberCenter[0], 1f - kit.numberCenter[1]));
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
t.raycastTarget = false;
}
if (st == NodeState.Clear)
{
var so = boss ? data.flagBossStars : data.flagStars;
아웃게임 1차(PD #1093 세션 A) — 본영 로비 · 세이브 · 군량 · 영웅(레벨·승급 6칸·진화·스킬 표시) · 편성(전열 3/후열 2 · 프리셋 3) · 거래(뽑기·골드 장비 상점) · 스테이지 보상·별 3·소탕 - 데이터: 기획 tables/ 12장 → Assets/Data/OutGame/*.csv · 메뉴 TKS/Import OutGame Data(Editor/DataImporter) → Resources/OutGame 9 자산(HeroDb·GearDb·GachaConfig·EconomyConfig·RewardTable·LevelTable·PromotionTable·EvolveTable·SkillInfoDb) · 검증(행 수·필수 열·id 유일·hero↔skill↔gear·확률 합) 오류 시 자산 불변 · BalanceConfig.heroes[]/HeroDef 삭제 → HeroDb(기존 5인 id 유지) · economy.csv 키 17 + gacha.csv 키 2 추가(기획서 본문 값 · C45) - 세이브: persistentDataPath/save.json · ver 1 · 즉시 저장 · 오프라인 군량 회복 · 일일 초기화 · 신규 유저 = 유비·관우·장비·조운·황충 Lv1 녹 ★=희귀도 · 골드 1000 · 보옥 300 · 군량 30 · 테스트·캡처 = 메모리 전용 - 화면(uGUI 와이어프레임 · img03·06·08·11): 시작 = 본영 로비(출정 → 월드맵 · 편성 · 연무장/보물/내정 준비 중 · 동맹 추후) · 재화 바(월드맵 포함 · 군량 타이머) · 하단 탭 5 · ◀/Esc 일관 · 영웅 목록·상세·상세정보·도감 · 편성(탭·드래그) · 뽑기(천장 n/80 · 확률 공개 · 첫 10연 무료 · 10연 ★★ 보장 · 카드 순차 공개) · 장비 상점(흰/녹 6종 일일 · sell×5 · 새로고침 보옥 20) - 전투 연결: BattleManager.LineupProvider/Deployed(LineupEntry · §3-2 스탯 · 방어 배율 생성 뒤) · playerSpawnPoints = 전열 (−4/0/4, −12) · 후열 (−2/2, −14) · WorldMapScreen 훅(팝업 군량·보상·별 · 입장 군량 · 노드 별 star_on/off · 소탕 · ◀ 본영 · TopInset) · 결과 패널(별 3 조건 · 골드·경험·보옥·장비) · GameBootstrap/AutoPlayDriver 로비 시작 - B 세션 파일(ActionResolver·Combat·UnitView·BattleHUD·SlingshotInput·EnemyAI) 미변경 - 테스트 56/56(기존 41 유지 · 신규 OutGameTests 15) · console error 0 · 사본 GUI 캡처 11장(DataImporter.CaptureOutGame) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:11:10 +00:00
int stars = StarsOf != null ? StarsOf(nodeStages[i]) : int.MaxValue; // 아웃게임 세이브 별(#1093 §6)
for (int k = 0; k + 1 < so.Length; k += 2) Piece(k / 2 < stars ? "star_on" : "star_off", slots[i] + new Vector2(so[k], so[k + 1]), false);
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
}
if (st == NodeState.Open)
{
var co = boss ? data.flagBossCursor : data.flagCursor;
var cimg = Piece("cursor", slots[i] + V(co), false);
if (cimg != null)
{
cursor = cimg.rectTransform;
cursorBase = cursor.anchoredPosition;
// 커서 = 매 프레임 위아래 흔들림 → 자기 캔버스(맵·노드 전체를 매 프레임 다시 묶지 않게 · PD 2026-11-10)
UiLayer.Nest(cimg.gameObject, UiRate.Frame, false);
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
}
}
}
// 처음 위치 = 도전할 노드(없으면 출발)
int focus = Mathf.Clamp(Mathf.Min(cleared, slots.Length - 1), 0, Mathf.Max(0, slots.Length - 1));
if (slots.Length > 0) ScrollTo(slots[focus]);
}
/// <summary>맵 px 지점을 화면 가운데로(맵 끝에서 멈춤).</summary>
public void ScrollTo(Vector2 p)
{
Canvas.ForceUpdateCanvases();
var vr = viewport.rect;
float w = data.mapSize[0], h = data.mapSize[1];
float nx = w > vr.width ? Mathf.Clamp01((p.x - vr.width / 2f) / (w - vr.width)) : 0f;
float ny = h > vr.height ? Mathf.Clamp01((p.y - vr.height / 2f) / (h - vr.height)) : 0f;
scroll.StopMovement();
scroll.normalizedPosition = new Vector2(nx, 1f - ny);
}
public NodeState StateOf(int ch, int node)
{
if (!HasData || !ChapterUnlocked(ch)) return NodeState.Lock;
int cleared = WorldProgress.Cleared(ch);
if (node < cleared) return NodeState.Clear;
return node == cleared ? NodeState.Open : NodeState.Lock;
}
public bool ChapterUnlocked(int ch)
{
if (!HasData || ch < 0 || ch >= cfg.chapters.Length) return false;
return ch == 0 || WorldProgress.Cleared(ch - 1) >= NodesIn(ch - 1);
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
}
// ---------- 팝업 ----------
void OnNodeClicked(int node)
{
if (Time.unscaledTime < inputBlockUntil) return;
OpenPopup(node);
}
public void OpenPopup(int node)
{
if (!HasData) return;
int si = StageIndexOf(chapter, node);
if (si < 0) return;
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
popupNode = node;
var st = StateOf(chapter, node);
var def = cfg.chapters[chapter];
var stage = cfg.stages[si];
string tag = stage.kind == StageKind.Boss ? " 보스" : stage.kind == StageKind.Elite ? " 엘리트" : "";
popupTitle.text = def.no + "-" + stage.stage + tag + "\n제" + def.no + "장 " + def.title;
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
var body = new System.Text.StringBuilder();
body.Append(stage.title);
if (!string.IsNullOrEmpty(stage.place)) body.Append("\n<size=26>").Append(stage.place).Append(string.IsNullOrEmpty(stage.bgTheme) ? "" : " · " + stage.bgTheme).Append("</size>");
body.Append("\n\n").Append(EnemySummary(stage));
아웃게임 1차(PD #1093 세션 A) — 본영 로비 · 세이브 · 군량 · 영웅(레벨·승급 6칸·진화·스킬 표시) · 편성(전열 3/후열 2 · 프리셋 3) · 거래(뽑기·골드 장비 상점) · 스테이지 보상·별 3·소탕 - 데이터: 기획 tables/ 12장 → Assets/Data/OutGame/*.csv · 메뉴 TKS/Import OutGame Data(Editor/DataImporter) → Resources/OutGame 9 자산(HeroDb·GearDb·GachaConfig·EconomyConfig·RewardTable·LevelTable·PromotionTable·EvolveTable·SkillInfoDb) · 검증(행 수·필수 열·id 유일·hero↔skill↔gear·확률 합) 오류 시 자산 불변 · BalanceConfig.heroes[]/HeroDef 삭제 → HeroDb(기존 5인 id 유지) · economy.csv 키 17 + gacha.csv 키 2 추가(기획서 본문 값 · C45) - 세이브: persistentDataPath/save.json · ver 1 · 즉시 저장 · 오프라인 군량 회복 · 일일 초기화 · 신규 유저 = 유비·관우·장비·조운·황충 Lv1 녹 ★=희귀도 · 골드 1000 · 보옥 300 · 군량 30 · 테스트·캡처 = 메모리 전용 - 화면(uGUI 와이어프레임 · img03·06·08·11): 시작 = 본영 로비(출정 → 월드맵 · 편성 · 연무장/보물/내정 준비 중 · 동맹 추후) · 재화 바(월드맵 포함 · 군량 타이머) · 하단 탭 5 · ◀/Esc 일관 · 영웅 목록·상세·상세정보·도감 · 편성(탭·드래그) · 뽑기(천장 n/80 · 확률 공개 · 첫 10연 무료 · 10연 ★★ 보장 · 카드 순차 공개) · 장비 상점(흰/녹 6종 일일 · sell×5 · 새로고침 보옥 20) - 전투 연결: BattleManager.LineupProvider/Deployed(LineupEntry · §3-2 스탯 · 방어 배율 생성 뒤) · playerSpawnPoints = 전열 (−4/0/4, −12) · 후열 (−2/2, −14) · WorldMapScreen 훅(팝업 군량·보상·별 · 입장 군량 · 노드 별 star_on/off · 소탕 · ◀ 본영 · TopInset) · 결과 패널(별 3 조건 · 골드·경험·보옥·장비) · GameBootstrap/AutoPlayDriver 로비 시작 - B 세션 파일(ActionResolver·Combat·UnitView·BattleHUD·SlingshotInput·EnemyAI) 미변경 - 테스트 56/56(기존 41 유지 · 신규 OutGameTests 15) · console error 0 · 사본 GUI 캡처 11장(DataImporter.CaptureOutGame) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:11:10 +00:00
if (PopupInfo != null)
{
var extra = PopupInfo(si);
if (!string.IsNullOrEmpty(extra)) body.Append("\n\n").Append(extra);
}
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
if (st == NodeState.Lock) body.Append("\n\n잠긴 스테이지 — 앞 스테이지를 먼저 깨세요");
popupBody.text = body.ToString();
popupGo.interactable = st != NodeState.Lock;
아웃게임 1차(PD #1093 세션 A) — 본영 로비 · 세이브 · 군량 · 영웅(레벨·승급 6칸·진화·스킬 표시) · 편성(전열 3/후열 2 · 프리셋 3) · 거래(뽑기·골드 장비 상점) · 스테이지 보상·별 3·소탕 - 데이터: 기획 tables/ 12장 → Assets/Data/OutGame/*.csv · 메뉴 TKS/Import OutGame Data(Editor/DataImporter) → Resources/OutGame 9 자산(HeroDb·GearDb·GachaConfig·EconomyConfig·RewardTable·LevelTable·PromotionTable·EvolveTable·SkillInfoDb) · 검증(행 수·필수 열·id 유일·hero↔skill↔gear·확률 합) 오류 시 자산 불변 · BalanceConfig.heroes[]/HeroDef 삭제 → HeroDb(기존 5인 id 유지) · economy.csv 키 17 + gacha.csv 키 2 추가(기획서 본문 값 · C45) - 세이브: persistentDataPath/save.json · ver 1 · 즉시 저장 · 오프라인 군량 회복 · 일일 초기화 · 신규 유저 = 유비·관우·장비·조운·황충 Lv1 녹 ★=희귀도 · 골드 1000 · 보옥 300 · 군량 30 · 테스트·캡처 = 메모리 전용 - 화면(uGUI 와이어프레임 · img03·06·08·11): 시작 = 본영 로비(출정 → 월드맵 · 편성 · 연무장/보물/내정 준비 중 · 동맹 추후) · 재화 바(월드맵 포함 · 군량 타이머) · 하단 탭 5 · ◀/Esc 일관 · 영웅 목록·상세·상세정보·도감 · 편성(탭·드래그) · 뽑기(천장 n/80 · 확률 공개 · 첫 10연 무료 · 10연 ★★ 보장 · 카드 순차 공개) · 장비 상점(흰/녹 6종 일일 · sell×5 · 새로고침 보옥 20) - 전투 연결: BattleManager.LineupProvider/Deployed(LineupEntry · §3-2 스탯 · 방어 배율 생성 뒤) · playerSpawnPoints = 전열 (−4/0/4, −12) · 후열 (−2/2, −14) · WorldMapScreen 훅(팝업 군량·보상·별 · 입장 군량 · 노드 별 star_on/off · 소탕 · ◀ 본영 · TopInset) · 결과 패널(별 3 조건 · 골드·경험·보옥·장비) · GameBootstrap/AutoPlayDriver 로비 시작 - B 세션 파일(ActionResolver·Combat·UnitView·BattleHUD·SlingshotInput·EnemyAI) 미변경 - 테스트 56/56(기존 41 유지 · 신규 OutGameTests 15) · console error 0 · 사본 GUI 캡처 11장(DataImporter.CaptureOutGame) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:11:10 +00:00
bool sweep = st == NodeState.Clear && CanSweep != null && Sweep != null && CanSweep(si);
popupSweep.gameObject.SetActive(sweep);
전투 결과 · 공용 팝업 · 거래 비주얼 개선 = Fable 제안서 §4-2~§4-4 구현(#1104 · PD 2026-11-09) - 전투 결과: 별 받침 원 + 큰 별(Icon_Star_On/Off 한 벌) 0.15 s 튀김(UiPop) · 조건 행 3(체크/엑스) · 보상 타일(ItemFrame 5층 + 수량 칩 · 장비 = 등급 칸 · 상자) · 「다시」(같은 노드 재출전 · 군량 확인 · WorldMapScreen.RetryLast · 화면 탭은 이 버튼 위만 제외 = SlingshotInput.HoldResultTap) + 「확인」 Primary 노랑 · 리본 뒤 금빛(호흡) - 군량 팝업: 필드 인셋 · 현재 군량 블록 · 교환 행 2(비용 → 군량 · 오늘 횟수 · Secondary 하늘/녹 · 다 쓰면 회색) · 닫기 = X 만 - 스테이지 팝업: 필드 인셋 · 적 구성 병종 원 ×n + 장수 칩 · 보상 타일 4(첫 클리어 뱃지) · 별 조건 행 3 · 출정 = 붉은 Primary + 군량 비용 · 소탕 = 녹 Secondary · 닫기 버튼 삭제(PopupFill · CostOf 훅) - 거래(뽑기): 목록 바탕 · 서브탭 Round10 · 배너 아래 문양 띠 + 「픽업」 뱃지 · 천장 = 레벨형 게이지 + 노랑 배지 · 확률 = 섹션 패널 + 제목 띠 + 행 3(별 · 바 · %) · 1회 Secondary 하늘 + 보옥 비용 · 10연 Primary 노랑 + 「첫 무료」 꼬리 칩 · 각주 → ⓘ 팝업 - UiKit 공용 부품 ②: At · SkinBtn · BtnCost · SubTab/SetSubTab · Gauge/SetGauge · InfoChip · QtyChip · RewardTile · CondRow · SubTitle - 테마 행 추가(ui_theme.csv): 버튼 btn_l_yellow·btn_l_red · 소제목 선 · 큰 별 · 뱃지 · 배너 문양 · 상자 색(구 TreasureScreen.ChestColor 상수 이관 준비) 등 - 테스트 117/117 · console error 0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 09:03:43 +00:00
if (popupField != null && PopupFill != null)
{
// 팩 팝업(#1104): 본문 = 필드 안 그림 · 출정(붉은 Primary + 군량 비용) · 소탕(녹 Secondary) 왼쪽
popupBody.gameObject.SetActive(false);
popupField.gameObject.SetActive(true);
foreach (Transform c in popupField) c.gameObject.SetActive(false);
for (int i = popupField.childCount - 1; i >= 0; i--) Destroy(popupField.GetChild(i).gameObject);
PopupFill(si, st == NodeState.Lock, popupField);
popupGoLabel.text = st == NodeState.Lock ? "잠김" : st == NodeState.Clear ? "다시 출정" : "출정";
if (popupCode != null)
{
popupCode.text = def.no + "-" + stage.stage + (stage.kind == StageKind.Boss ? " 보스" : stage.kind == StageKind.Elite ? " 정예" : "");
popupTitle.text = "제" + def.no + "장 " + def.title;
}
전투 결과 · 공용 팝업 · 거래 비주얼 개선 = Fable 제안서 §4-2~§4-4 구현(#1104 · PD 2026-11-09) - 전투 결과: 별 받침 원 + 큰 별(Icon_Star_On/Off 한 벌) 0.15 s 튀김(UiPop) · 조건 행 3(체크/엑스) · 보상 타일(ItemFrame 5층 + 수량 칩 · 장비 = 등급 칸 · 상자) · 「다시」(같은 노드 재출전 · 군량 확인 · WorldMapScreen.RetryLast · 화면 탭은 이 버튼 위만 제외 = SlingshotInput.HoldResultTap) + 「확인」 Primary 노랑 · 리본 뒤 금빛(호흡) - 군량 팝업: 필드 인셋 · 현재 군량 블록 · 교환 행 2(비용 → 군량 · 오늘 횟수 · Secondary 하늘/녹 · 다 쓰면 회색) · 닫기 = X 만 - 스테이지 팝업: 필드 인셋 · 적 구성 병종 원 ×n + 장수 칩 · 보상 타일 4(첫 클리어 뱃지) · 별 조건 행 3 · 출정 = 붉은 Primary + 군량 비용 · 소탕 = 녹 Secondary · 닫기 버튼 삭제(PopupFill · CostOf 훅) - 거래(뽑기): 목록 바탕 · 서브탭 Round10 · 배너 아래 문양 띠 + 「픽업」 뱃지 · 천장 = 레벨형 게이지 + 노랑 배지 · 확률 = 섹션 패널 + 제목 띠 + 행 3(별 · 바 · %) · 1회 Secondary 하늘 + 보옥 비용 · 10연 Primary 노랑 + 「첫 무료」 꼬리 칩 · 각주 → ⓘ 팝업 - UiKit 공용 부품 ②: At · SkinBtn · BtnCost · SubTab/SetSubTab · Gauge/SetGauge · InfoChip · QtyChip · RewardTile · CondRow · SubTitle - 테마 행 추가(ui_theme.csv): 버튼 btn_l_yellow·btn_l_red · 소제목 선 · 큰 별 · 뱃지 · 배너 문양 · 상자 색(구 TreasureScreen.ChestColor 상수 이관 준비) 등 - 테스트 117/117 · console error 0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 09:03:43 +00:00
if (popupCost != null) popupCost.text = CostOf != null ? CostOf(si).ToString() : "";
((RectTransform)popupGo.transform).anchoredPosition = new Vector2(sweep ? 390f : 240f, -PopupBtnY);
}
else
{
popupBody.gameObject.SetActive(true);
if (popupField != null) popupField.gameObject.SetActive(false);
popupGoLabel.text = st == NodeState.Clear ? "다시 출전" : "출전";
}
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
popup.SetActive(true);
}
아웃게임 1차(PD #1093 세션 A) — 본영 로비 · 세이브 · 군량 · 영웅(레벨·승급 6칸·진화·스킬 표시) · 편성(전열 3/후열 2 · 프리셋 3) · 거래(뽑기·골드 장비 상점) · 스테이지 보상·별 3·소탕 - 데이터: 기획 tables/ 12장 → Assets/Data/OutGame/*.csv · 메뉴 TKS/Import OutGame Data(Editor/DataImporter) → Resources/OutGame 9 자산(HeroDb·GearDb·GachaConfig·EconomyConfig·RewardTable·LevelTable·PromotionTable·EvolveTable·SkillInfoDb) · 검증(행 수·필수 열·id 유일·hero↔skill↔gear·확률 합) 오류 시 자산 불변 · BalanceConfig.heroes[]/HeroDef 삭제 → HeroDb(기존 5인 id 유지) · economy.csv 키 17 + gacha.csv 키 2 추가(기획서 본문 값 · C45) - 세이브: persistentDataPath/save.json · ver 1 · 즉시 저장 · 오프라인 군량 회복 · 일일 초기화 · 신규 유저 = 유비·관우·장비·조운·황충 Lv1 녹 ★=희귀도 · 골드 1000 · 보옥 300 · 군량 30 · 테스트·캡처 = 메모리 전용 - 화면(uGUI 와이어프레임 · img03·06·08·11): 시작 = 본영 로비(출정 → 월드맵 · 편성 · 연무장/보물/내정 준비 중 · 동맹 추후) · 재화 바(월드맵 포함 · 군량 타이머) · 하단 탭 5 · ◀/Esc 일관 · 영웅 목록·상세·상세정보·도감 · 편성(탭·드래그) · 뽑기(천장 n/80 · 확률 공개 · 첫 10연 무료 · 10연 ★★ 보장 · 카드 순차 공개) · 장비 상점(흰/녹 6종 일일 · sell×5 · 새로고침 보옥 20) - 전투 연결: BattleManager.LineupProvider/Deployed(LineupEntry · §3-2 스탯 · 방어 배율 생성 뒤) · playerSpawnPoints = 전열 (−4/0/4, −12) · 후열 (−2/2, −14) · WorldMapScreen 훅(팝업 군량·보상·별 · 입장 군량 · 노드 별 star_on/off · 소탕 · ◀ 본영 · TopInset) · 결과 패널(별 3 조건 · 골드·경험·보옥·장비) · GameBootstrap/AutoPlayDriver 로비 시작 - B 세션 파일(ActionResolver·Combat·UnitView·BattleHUD·SlingshotInput·EnemyAI) 미변경 - 테스트 56/56(기존 41 유지 · 신규 OutGameTests 15) · console error 0 · 사본 GUI 캡처 11장(DataImporter.CaptureOutGame) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:11:10 +00:00
void OnSweepClicked()
{
if (popupNode < 0 || Sweep == null) return;
int si = StageIndexOf(chapter, popupNode);
if (si >= 0) Sweep(si);
}
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
public void ClosePopup()
{
popupNode = -1;
if (popup != null) popup.SetActive(false);
}
public void ConfirmPopup()
{
if (popupNode < 0) return;
if (StateOf(chapter, popupNode) == NodeState.Lock) return;
아웃게임 1차(PD #1093 세션 A) — 본영 로비 · 세이브 · 군량 · 영웅(레벨·승급 6칸·진화·스킬 표시) · 편성(전열 3/후열 2 · 프리셋 3) · 거래(뽑기·골드 장비 상점) · 스테이지 보상·별 3·소탕 - 데이터: 기획 tables/ 12장 → Assets/Data/OutGame/*.csv · 메뉴 TKS/Import OutGame Data(Editor/DataImporter) → Resources/OutGame 9 자산(HeroDb·GearDb·GachaConfig·EconomyConfig·RewardTable·LevelTable·PromotionTable·EvolveTable·SkillInfoDb) · 검증(행 수·필수 열·id 유일·hero↔skill↔gear·확률 합) 오류 시 자산 불변 · BalanceConfig.heroes[]/HeroDef 삭제 → HeroDb(기존 5인 id 유지) · economy.csv 키 17 + gacha.csv 키 2 추가(기획서 본문 값 · C45) - 세이브: persistentDataPath/save.json · ver 1 · 즉시 저장 · 오프라인 군량 회복 · 일일 초기화 · 신규 유저 = 유비·관우·장비·조운·황충 Lv1 녹 ★=희귀도 · 골드 1000 · 보옥 300 · 군량 30 · 테스트·캡처 = 메모리 전용 - 화면(uGUI 와이어프레임 · img03·06·08·11): 시작 = 본영 로비(출정 → 월드맵 · 편성 · 연무장/보물/내정 준비 중 · 동맹 추후) · 재화 바(월드맵 포함 · 군량 타이머) · 하단 탭 5 · ◀/Esc 일관 · 영웅 목록·상세·상세정보·도감 · 편성(탭·드래그) · 뽑기(천장 n/80 · 확률 공개 · 첫 10연 무료 · 10연 ★★ 보장 · 카드 순차 공개) · 장비 상점(흰/녹 6종 일일 · sell×5 · 새로고침 보옥 20) - 전투 연결: BattleManager.LineupProvider/Deployed(LineupEntry · §3-2 스탯 · 방어 배율 생성 뒤) · playerSpawnPoints = 전열 (−4/0/4, −12) · 후열 (−2/2, −14) · WorldMapScreen 훅(팝업 군량·보상·별 · 입장 군량 · 노드 별 star_on/off · 소탕 · ◀ 본영 · TopInset) · 결과 패널(별 3 조건 · 골드·경험·보옥·장비) · GameBootstrap/AutoPlayDriver 로비 시작 - B 세션 파일(ActionResolver·Combat·UnitView·BattleHUD·SlingshotInput·EnemyAI) 미변경 - 테스트 56/56(기존 41 유지 · 신규 OutGameTests 15) · console error 0 · 사본 GUI 캡처 11장(DataImporter.CaptureOutGame) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:11:10 +00:00
if (TryEnter != null && !TryEnter(StageIndexOf(chapter, popupNode))) return; // 군량 부족(#1093 §2)
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
EnterStage(chapter, popupNode);
}
/// <summary>노드의 전투로 들어간다(월드맵 닫음 · HUD·조작 켬).</summary>
public void EnterStage(int ch, int node)
{
if (!HasData)
{
battle.StartStage(0);
return;
}
chapter = Mathf.Clamp(ch, 0, cfg.chapters.Length - 1);
int si = StageIndexOf(chapter, node);
if (si < 0) return;
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
entryChapter = chapter;
entryNode = node;
ClosePopup();
root.SetActive(false);
if (hud != null) hud.gameObject.SetActive(true);
if (sling != null) sling.enabled = true;
battle.StartStage(si);
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
}
전투 결과 · 공용 팝업 · 거래 비주얼 개선 = Fable 제안서 §4-2~§4-4 구현(#1104 · PD 2026-11-09) - 전투 결과: 별 받침 원 + 큰 별(Icon_Star_On/Off 한 벌) 0.15 s 튀김(UiPop) · 조건 행 3(체크/엑스) · 보상 타일(ItemFrame 5층 + 수량 칩 · 장비 = 등급 칸 · 상자) · 「다시」(같은 노드 재출전 · 군량 확인 · WorldMapScreen.RetryLast · 화면 탭은 이 버튼 위만 제외 = SlingshotInput.HoldResultTap) + 「확인」 Primary 노랑 · 리본 뒤 금빛(호흡) - 군량 팝업: 필드 인셋 · 현재 군량 블록 · 교환 행 2(비용 → 군량 · 오늘 횟수 · Secondary 하늘/녹 · 다 쓰면 회색) · 닫기 = X 만 - 스테이지 팝업: 필드 인셋 · 적 구성 병종 원 ×n + 장수 칩 · 보상 타일 4(첫 클리어 뱃지) · 별 조건 행 3 · 출정 = 붉은 Primary + 군량 비용 · 소탕 = 녹 Secondary · 닫기 버튼 삭제(PopupFill · CostOf 훅) - 거래(뽑기): 목록 바탕 · 서브탭 Round10 · 배너 아래 문양 띠 + 「픽업」 뱃지 · 천장 = 레벨형 게이지 + 노랑 배지 · 확률 = 섹션 패널 + 제목 띠 + 행 3(별 · 바 · %) · 1회 Secondary 하늘 + 보옥 비용 · 10연 Primary 노랑 + 「첫 무료」 꼬리 칩 · 각주 → ⓘ 팝업 - UiKit 공용 부품 ②: At · SkinBtn · BtnCost · SubTab/SetSubTab · Gauge/SetGauge · InfoChip · QtyChip · RewardTile · CondRow · SubTitle - 테마 행 추가(ui_theme.csv): 버튼 btn_l_yellow·btn_l_red · 소제목 선 · 큰 별 · 뱃지 · 배너 문양 · 상자 색(구 TreasureScreen.ChestColor 상수 이관 준비) 등 - 테스트 117/117 · console error 0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 09:03:43 +00:00
/// <summary>결과 화면 「다시」(#1104) — 결과 처리(진행 기록 · 월드맵 복귀)를 한 뒤 같은 노드로 다시 출전 · 군량이 모자라면 월드맵에 남음(충전 팝업).</summary>
public void RetryLast()
{
int ch = entryChapter >= 0 ? entryChapter : chapter;
int node = entryNode;
battle.ContinueAfterResult();
if (node < 0 || !HasData) return;
if (TryEnter != null && !TryEnter(StageIndexOf(ch, node))) return;
EnterStage(ch, node);
}
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
void OnBattleResult(bool win)
{
int ch = entryChapter >= 0 ? entryChapter : chapter;
if (win && entryNode >= 0)
{
WorldProgress.MarkCleared(ch, entryNode);
// 챕터 마지막 스테이지를 깨면 다음 챕터 맵으로
if (entryNode == NodesIn(ch) - 1 && ch + 1 < cfg.chapters.Length) ch++;
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
}
entryChapter = entryNode = -1;
Show(ch);
}
/// <summary>적 수·병종 + 장수(보스 · 엘리트) 이름.</summary>
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
static string EnemySummary(BalanceConfig.StageDef stage)
{
var counts = new int[UnitTypeInfo.Count];
var bosses = new List<string>();
var elites = new List<string>();
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
foreach (var e in stage.enemies)
{
counts[(int)e.type]++;
if (e.isBoss) bosses.Add(e.name);
else if (e.isGeneral) elites.Add(e.name);
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
}
var sb = new System.Text.StringBuilder("적 " + stage.enemies.Count + "기 · ");
bool first = true;
for (int t = 0; t < counts.Length; t++)
{
if (counts[t] == 0) continue;
if (!first) sb.Append(" ");
sb.Append(UnitTypeInfo.Korean((UnitType)t)).Append(" ").Append(counts[t]);
first = false;
}
if (bosses.Count > 0) sb.Append("\n보스 ").Append(string.Join(" · ", bosses.ToArray()));
if (elites.Count > 0) sb.Append("\n장수 ").Append(string.Join(" · ", elites.ToArray()));
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
return sb.ToString();
}
전투 결과 · 공용 팝업 · 거래 비주얼 개선 = Fable 제안서 §4-2~§4-4 구현(#1104 · PD 2026-11-09) - 전투 결과: 별 받침 원 + 큰 별(Icon_Star_On/Off 한 벌) 0.15 s 튀김(UiPop) · 조건 행 3(체크/엑스) · 보상 타일(ItemFrame 5층 + 수량 칩 · 장비 = 등급 칸 · 상자) · 「다시」(같은 노드 재출전 · 군량 확인 · WorldMapScreen.RetryLast · 화면 탭은 이 버튼 위만 제외 = SlingshotInput.HoldResultTap) + 「확인」 Primary 노랑 · 리본 뒤 금빛(호흡) - 군량 팝업: 필드 인셋 · 현재 군량 블록 · 교환 행 2(비용 → 군량 · 오늘 횟수 · Secondary 하늘/녹 · 다 쓰면 회색) · 닫기 = X 만 - 스테이지 팝업: 필드 인셋 · 적 구성 병종 원 ×n + 장수 칩 · 보상 타일 4(첫 클리어 뱃지) · 별 조건 행 3 · 출정 = 붉은 Primary + 군량 비용 · 소탕 = 녹 Secondary · 닫기 버튼 삭제(PopupFill · CostOf 훅) - 거래(뽑기): 목록 바탕 · 서브탭 Round10 · 배너 아래 문양 띠 + 「픽업」 뱃지 · 천장 = 레벨형 게이지 + 노랑 배지 · 확률 = 섹션 패널 + 제목 띠 + 행 3(별 · 바 · %) · 1회 Secondary 하늘 + 보옥 비용 · 10연 Primary 노랑 + 「첫 무료」 꼬리 칩 · 각주 → ⓘ 팝업 - UiKit 공용 부품 ②: At · SkinBtn · BtnCost · SubTab/SetSubTab · Gauge/SetGauge · InfoChip · QtyChip · RewardTile · CondRow · SubTitle - 테마 행 추가(ui_theme.csv): 버튼 btn_l_yellow·btn_l_red · 소제목 선 · 큰 별 · 뱃지 · 배너 문양 · 상자 색(구 TreasureScreen.ChestColor 상수 이관 준비) 등 - 테스트 117/117 · console error 0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 09:03:43 +00:00
// 팩 스테이지 팝업 배치(UI px · 패널 왼쪽 위 기준 · #1104)
const float PopupW = 900f;
const float PopupH = 1160f;
const float PopupBtnY = PopupH - 52f - 104f;
전투 결과 · 공용 팝업 · 거래 비주얼 개선 = Fable 제안서 §4-2~§4-4 구현(#1104 · PD 2026-11-09) - 전투 결과: 별 받침 원 + 큰 별(Icon_Star_On/Off 한 벌) 0.15 s 튀김(UiPop) · 조건 행 3(체크/엑스) · 보상 타일(ItemFrame 5층 + 수량 칩 · 장비 = 등급 칸 · 상자) · 「다시」(같은 노드 재출전 · 군량 확인 · WorldMapScreen.RetryLast · 화면 탭은 이 버튼 위만 제외 = SlingshotInput.HoldResultTap) + 「확인」 Primary 노랑 · 리본 뒤 금빛(호흡) - 군량 팝업: 필드 인셋 · 현재 군량 블록 · 교환 행 2(비용 → 군량 · 오늘 횟수 · Secondary 하늘/녹 · 다 쓰면 회색) · 닫기 = X 만 - 스테이지 팝업: 필드 인셋 · 적 구성 병종 원 ×n + 장수 칩 · 보상 타일 4(첫 클리어 뱃지) · 별 조건 행 3 · 출정 = 붉은 Primary + 군량 비용 · 소탕 = 녹 Secondary · 닫기 버튼 삭제(PopupFill · CostOf 훅) - 거래(뽑기): 목록 바탕 · 서브탭 Round10 · 배너 아래 문양 띠 + 「픽업」 뱃지 · 천장 = 레벨형 게이지 + 노랑 배지 · 확률 = 섹션 패널 + 제목 띠 + 행 3(별 · 바 · %) · 1회 Secondary 하늘 + 보옥 비용 · 10연 Primary 노랑 + 「첫 무료」 꼬리 칩 · 각주 → ⓘ 팝업 - UiKit 공용 부품 ②: At · SkinBtn · BtnCost · SubTab/SetSubTab · Gauge/SetGauge · InfoChip · QtyChip · RewardTile · CondRow · SubTitle - 테마 행 추가(ui_theme.csv): 버튼 btn_l_yellow·btn_l_red · 소제목 선 · 큰 별 · 뱃지 · 배너 문양 · 상자 색(구 TreasureScreen.ChestColor 상수 이관 준비) 등 - 테스트 117/117 · console error 0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 09:03:43 +00:00
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
void BuildPopup()
{
var dim = Img("Popup", root.transform, null, Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f), Vector2.zero, Vector2.zero);
dim.color = new Color(0f, 0f, 0f, 0.6f);
dim.raycastTarget = true;
popup = dim.gameObject;
UiLayer.Nest(popup, UiRate.Event, true); // 스테이지 팝업 = 자기 캔버스(열 때·소탕 때만)
아웃게임 1차(PD #1093 세션 A) — 본영 로비 · 세이브 · 군량 · 영웅(레벨·승급 6칸·진화·스킬 표시) · 편성(전열 3/후열 2 · 프리셋 3) · 거래(뽑기·골드 장비 상점) · 스테이지 보상·별 3·소탕 - 데이터: 기획 tables/ 12장 → Assets/Data/OutGame/*.csv · 메뉴 TKS/Import OutGame Data(Editor/DataImporter) → Resources/OutGame 9 자산(HeroDb·GearDb·GachaConfig·EconomyConfig·RewardTable·LevelTable·PromotionTable·EvolveTable·SkillInfoDb) · 검증(행 수·필수 열·id 유일·hero↔skill↔gear·확률 합) 오류 시 자산 불변 · BalanceConfig.heroes[]/HeroDef 삭제 → HeroDb(기존 5인 id 유지) · economy.csv 키 17 + gacha.csv 키 2 추가(기획서 본문 값 · C45) - 세이브: persistentDataPath/save.json · ver 1 · 즉시 저장 · 오프라인 군량 회복 · 일일 초기화 · 신규 유저 = 유비·관우·장비·조운·황충 Lv1 녹 ★=희귀도 · 골드 1000 · 보옥 300 · 군량 30 · 테스트·캡처 = 메모리 전용 - 화면(uGUI 와이어프레임 · img03·06·08·11): 시작 = 본영 로비(출정 → 월드맵 · 편성 · 연무장/보물/내정 준비 중 · 동맹 추후) · 재화 바(월드맵 포함 · 군량 타이머) · 하단 탭 5 · ◀/Esc 일관 · 영웅 목록·상세·상세정보·도감 · 편성(탭·드래그) · 뽑기(천장 n/80 · 확률 공개 · 첫 10연 무료 · 10연 ★★ 보장 · 카드 순차 공개) · 장비 상점(흰/녹 6종 일일 · sell×5 · 새로고침 보옥 20) - 전투 연결: BattleManager.LineupProvider/Deployed(LineupEntry · §3-2 스탯 · 방어 배율 생성 뒤) · playerSpawnPoints = 전열 (−4/0/4, −12) · 후열 (−2/2, −14) · WorldMapScreen 훅(팝업 군량·보상·별 · 입장 군량 · 노드 별 star_on/off · 소탕 · ◀ 본영 · TopInset) · 결과 패널(별 3 조건 · 골드·경험·보옥·장비) · GameBootstrap/AutoPlayDriver 로비 시작 - B 세션 파일(ActionResolver·Combat·UnitView·BattleHUD·SlingshotInput·EnemyAI) 미변경 - 테스트 56/56(기존 41 유지 · 신규 OutGameTests 15) · console error 0 · 사본 GUI 캡처 11장(DataImporter.CaptureOutGame) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:11:10 +00:00
// 아웃게임 줄(군량 · 보상 · 별 · #1093)이 들어가도록 2026-11-05 패널을 키움(880×760 → 900×1080)
var panel = Img("Panel", popup.transform, Sprite("plate"), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 40f), new Vector2(900f, 1080f));
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
panel.type = Image.Type.Sliced;
panel.raycastTarget = true;
UI 리뉴얼 A-2~A-4 화면 적용(PD #1100) — 팩 부품 + UI 테마(id 치환) · 화면 10종 · 인박스 ui kind - 테마: SOT Assets/Data/UI/ui_theme.csv(색 57 · 스킨 32 · 아이콘 63 · 제목 폰트) → 메뉴 TKS/Import UI Theme → Resources/UI/UITheme.asset (Runtime/UI/UITheme · UISkin · Editor/UIThemeImporter · ProjectSetup 에서도 임포트) · 화면 코드는 id 로만 묻는다(스프라이트 경로 0) - 신규 제작(B) 치환: Assets/UI/Samguk/**/<id>.png → 임포트 시 같은 id 스킨·아이콘 자동 치환(팩 보존 · 새 id = 아이콘 추가) · Tools/apply_delivery.py ui kind(md5 → Samguk/<group> · gim_* → Resources/Gimmicks/Art · ui_delivered.csv) - 공통: UiKit(카드 = BorderFrame_Round20 틴트 · 버튼 = Button01_s + 광택 · 원 · 진행 바 = Slider_Basic01 · 초상 틀 · 등급 칸 ItemFrame02 · 별 줄 · 병종 배지) · 재화 바(ResourceBar + cur_* 아이콘) · 하단 탭(선택 판 + PictoIcon) · 제목 띠 · 팝업(Popup Topber + 닫기 X) · 토스트 - 화면: 로비(키아트 04 배경 위쪽 ×1.22 · 출정·편성·연무장 아이콘) · 영웅(등급 칸 + 장비 아이콘 · 체크/알림 점 · 별 아이콘) · 편성 · 거래(배너 · 상자 아이콘) · 보물(상자 아이콘 · 포인트 배지) · 내정(보상 줄 · 도면·골드 아이콘) · 연무장 · 결과(리본 · 별) · 월드맵 스테이지 팝업만 팩(거점 kit 유지) - 전투: HUD 칩 · 턴 띠 · 원형 스킬 버튼 + 쿨 라디얼 · 유닛 체력 바 · 기믹 내구 핍 = 팩 슬라이더(월드 9-slice 사본 · 가운데 2 px) · 조준선 색 유지 - 3:4(1536×2048): 본문 비율 축소(UiFitHeight · 1080×1920 = 그대로) - 검증: 플레이모드 116/116(기존 115 + UIThemeTests 1) · 컴파일 0 · error 0 · 캡처 = DataImporter.CaptureUI(UICaptureDriver · 15장) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 14:20:57 +00:00
// 스테이지 팝업만 팩 Popup(PD #1100 · 거점 kit 유지) · 테마가 없으면 kit plate·banner
bool pack = UISkin.Apply(panel, "popup");
if (pack)
{
panel.color = UISkin.Col("paper", Color.white);
var band = Img("Head", panel.transform, null, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -6f), new Vector2(-14f, 150f));
UISkin.Apply(band, "popup_head");
band.color = UISkin.Col("header", Ink);
popupTitle = Label(band.transform, "", 38, Color.white, new Vector2(0.5f, 0.5f));
popupTitle.font = UISkin.TitleFont;
popupTitle.GetComponent<Outline>().effectColor = UISkin.Col("stroke", Ink);
var x = Img("Close", panel.transform, null, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(0.5f, 0.5f), new Vector2(-58f, -60f), new Vector2(86f, 88f));
UISkin.Apply(x, "close");
x.raycastTarget = true;
x.gameObject.AddComponent<Button>().onClick.AddListener(ClosePopup);
}
else
{
var head = Img("Head", panel.transform, Sprite("banner"), new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), new Vector2(760f, 112f));
head.type = Image.Type.Sliced;
var bk = data.Kit("banner");
popupTitle = Label(head.transform, "", 34, Paper, new Vector2(0.5f, 1f - (bk != null ? bk.numberCenter[1] : 0.4f)));
}
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
popupTitle.lineSpacing = 0.9f;
UI 리뉴얼 A-2~A-4 화면 적용(PD #1100) — 팩 부품 + UI 테마(id 치환) · 화면 10종 · 인박스 ui kind - 테마: SOT Assets/Data/UI/ui_theme.csv(색 57 · 스킨 32 · 아이콘 63 · 제목 폰트) → 메뉴 TKS/Import UI Theme → Resources/UI/UITheme.asset (Runtime/UI/UITheme · UISkin · Editor/UIThemeImporter · ProjectSetup 에서도 임포트) · 화면 코드는 id 로만 묻는다(스프라이트 경로 0) - 신규 제작(B) 치환: Assets/UI/Samguk/**/<id>.png → 임포트 시 같은 id 스킨·아이콘 자동 치환(팩 보존 · 새 id = 아이콘 추가) · Tools/apply_delivery.py ui kind(md5 → Samguk/<group> · gim_* → Resources/Gimmicks/Art · ui_delivered.csv) - 공통: UiKit(카드 = BorderFrame_Round20 틴트 · 버튼 = Button01_s + 광택 · 원 · 진행 바 = Slider_Basic01 · 초상 틀 · 등급 칸 ItemFrame02 · 별 줄 · 병종 배지) · 재화 바(ResourceBar + cur_* 아이콘) · 하단 탭(선택 판 + PictoIcon) · 제목 띠 · 팝업(Popup Topber + 닫기 X) · 토스트 - 화면: 로비(키아트 04 배경 위쪽 ×1.22 · 출정·편성·연무장 아이콘) · 영웅(등급 칸 + 장비 아이콘 · 체크/알림 점 · 별 아이콘) · 편성 · 거래(배너 · 상자 아이콘) · 보물(상자 아이콘 · 포인트 배지) · 내정(보상 줄 · 도면·골드 아이콘) · 연무장 · 결과(리본 · 별) · 월드맵 스테이지 팝업만 팩(거점 kit 유지) - 전투: HUD 칩 · 턴 띠 · 원형 스킬 버튼 + 쿨 라디얼 · 유닛 체력 바 · 기믹 내구 핍 = 팩 슬라이더(월드 9-slice 사본 · 가운데 2 px) · 조준선 색 유지 - 3:4(1536×2048): 본문 비율 축소(UiFitHeight · 1080×1920 = 그대로) - 검증: 플레이모드 116/116(기존 115 + UIThemeTests 1) · 컴파일 0 · error 0 · 캡처 = DataImporter.CaptureUI(UICaptureDriver · 15장) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 14:20:57 +00:00
popupBody = Label(panel.transform, "", 30, pack ? UISkin.Col("ink", new Color(0.25f, 0.15f, 0.1f)) : new Color(0.25f, 0.15f, 0.1f), new Vector2(0.5f, pack ? 0.545f : 0.56f));
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
popupBody.GetComponent<Outline>().enabled = false;
UI 리뉴얼 A-2~A-4 화면 적용(PD #1100) — 팩 부품 + UI 테마(id 치환) · 화면 10종 · 인박스 ui kind - 테마: SOT Assets/Data/UI/ui_theme.csv(색 57 · 스킨 32 · 아이콘 63 · 제목 폰트) → 메뉴 TKS/Import UI Theme → Resources/UI/UITheme.asset (Runtime/UI/UITheme · UISkin · Editor/UIThemeImporter · ProjectSetup 에서도 임포트) · 화면 코드는 id 로만 묻는다(스프라이트 경로 0) - 신규 제작(B) 치환: Assets/UI/Samguk/**/<id>.png → 임포트 시 같은 id 스킨·아이콘 자동 치환(팩 보존 · 새 id = 아이콘 추가) · Tools/apply_delivery.py ui kind(md5 → Samguk/<group> · gim_* → Resources/Gimmicks/Art · ui_delivered.csv) - 공통: UiKit(카드 = BorderFrame_Round20 틴트 · 버튼 = Button01_s + 광택 · 원 · 진행 바 = Slider_Basic01 · 초상 틀 · 등급 칸 ItemFrame02 · 별 줄 · 병종 배지) · 재화 바(ResourceBar + cur_* 아이콘) · 하단 탭(선택 판 + PictoIcon) · 제목 띠 · 팝업(Popup Topber + 닫기 X) · 토스트 - 화면: 로비(키아트 04 배경 위쪽 ×1.22 · 출정·편성·연무장 아이콘) · 영웅(등급 칸 + 장비 아이콘 · 체크/알림 점 · 별 아이콘) · 편성 · 거래(배너 · 상자 아이콘) · 보물(상자 아이콘 · 포인트 배지) · 내정(보상 줄 · 도면·골드 아이콘) · 연무장 · 결과(리본 · 별) · 월드맵 스테이지 팝업만 팩(거점 kit 유지) - 전투: HUD 칩 · 턴 띠 · 원형 스킬 버튼 + 쿨 라디얼 · 유닛 체력 바 · 기믹 내구 핍 = 팩 슬라이더(월드 9-slice 사본 · 가운데 2 px) · 조준선 색 유지 - 3:4(1536×2048): 본문 비율 축소(UiFitHeight · 1080×1920 = 그대로) - 검증: 플레이모드 116/116(기존 115 + UIThemeTests 1) · 컴파일 0 · error 0 · 캡처 = DataImporter.CaptureUI(UICaptureDriver · 15장) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 14:20:57 +00:00
popupBody.rectTransform.sizeDelta = new Vector2(800f, pack ? 640f : 720f);
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
popupBody.horizontalOverflow = HorizontalWrapMode.Wrap;
popupBody.supportRichText = true;
전투 결과 · 공용 팝업 · 거래 비주얼 개선 = Fable 제안서 §4-2~§4-4 구현(#1104 · PD 2026-11-09) - 전투 결과: 별 받침 원 + 큰 별(Icon_Star_On/Off 한 벌) 0.15 s 튀김(UiPop) · 조건 행 3(체크/엑스) · 보상 타일(ItemFrame 5층 + 수량 칩 · 장비 = 등급 칸 · 상자) · 「다시」(같은 노드 재출전 · 군량 확인 · WorldMapScreen.RetryLast · 화면 탭은 이 버튼 위만 제외 = SlingshotInput.HoldResultTap) + 「확인」 Primary 노랑 · 리본 뒤 금빛(호흡) - 군량 팝업: 필드 인셋 · 현재 군량 블록 · 교환 행 2(비용 → 군량 · 오늘 횟수 · Secondary 하늘/녹 · 다 쓰면 회색) · 닫기 = X 만 - 스테이지 팝업: 필드 인셋 · 적 구성 병종 원 ×n + 장수 칩 · 보상 타일 4(첫 클리어 뱃지) · 별 조건 행 3 · 출정 = 붉은 Primary + 군량 비용 · 소탕 = 녹 Secondary · 닫기 버튼 삭제(PopupFill · CostOf 훅) - 거래(뽑기): 목록 바탕 · 서브탭 Round10 · 배너 아래 문양 띠 + 「픽업」 뱃지 · 천장 = 레벨형 게이지 + 노랑 배지 · 확률 = 섹션 패널 + 제목 띠 + 행 3(별 · 바 · %) · 1회 Secondary 하늘 + 보옥 비용 · 10연 Primary 노랑 + 「첫 무료」 꼬리 칩 · 각주 → ⓘ 팝업 - UiKit 공용 부품 ②: At · SkinBtn · BtnCost · SubTab/SetSubTab · Gauge/SetGauge · InfoChip · QtyChip · RewardTile · CondRow · SubTitle - 테마 행 추가(ui_theme.csv): 버튼 btn_l_yellow·btn_l_red · 소제목 선 · 큰 별 · 뱃지 · 배너 문양 · 상자 색(구 TreasureScreen.ChestColor 상수 이관 준비) 등 - 테스트 117/117 · console error 0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 09:03:43 +00:00
if (pack && UISkin.Has("panel_field") && UISkin.Has("btn_l_red"))
{
// Fable 제안서 §4-3(#1104): 팝업 900×1160 · 본문 필드(panel_field 인셋 20) · 출정 = 붉은 Primary 420×104 + 군량 비용 · 소탕 = 녹 Secondary · 닫기 = X 만
panel.rectTransform.sizeDelta = new Vector2(PopupW, PopupH);
var field = Img("Field", panel.transform, null, Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f), Vector2.zero, Vector2.zero);
UISkin.Apply(field, "panel_field");
field.color = UISkin.Col("panel_field", Ink);
field.rectTransform.offsetMin = new Vector2(20f, PopupH - PopupBtnY + 16f);
field.rectTransform.offsetMax = new Vector2(-20f, -126f);
// 제목 띠 = 공용 팝업과 같은 h110 · #1F2138 · 왼쪽 스테이지 칩(검수 결함 6)
var head = panel.transform.Find("Head") as RectTransform;
if (head != null)
{
head.sizeDelta = new Vector2(head.sizeDelta.x, 110f);
head.GetComponent<Image>().color = UISkin.Col("popup_band", Ink);
popupCode = TKS.OutGame.UiKit.InfoChip(head, "Code", 30f, 27f, 190f, 56f, null, "", 30);
popupTitle.fontSize = 40;
}
전투 결과 · 공용 팝업 · 거래 비주얼 개선 = Fable 제안서 §4-2~§4-4 구현(#1104 · PD 2026-11-09) - 전투 결과: 별 받침 원 + 큰 별(Icon_Star_On/Off 한 벌) 0.15 s 튀김(UiPop) · 조건 행 3(체크/엑스) · 보상 타일(ItemFrame 5층 + 수량 칩 · 장비 = 등급 칸 · 상자) · 「다시」(같은 노드 재출전 · 군량 확인 · WorldMapScreen.RetryLast · 화면 탭은 이 버튼 위만 제외 = SlingshotInput.HoldResultTap) + 「확인」 Primary 노랑 · 리본 뒤 금빛(호흡) - 군량 팝업: 필드 인셋 · 현재 군량 블록 · 교환 행 2(비용 → 군량 · 오늘 횟수 · Secondary 하늘/녹 · 다 쓰면 회색) · 닫기 = X 만 - 스테이지 팝업: 필드 인셋 · 적 구성 병종 원 ×n + 장수 칩 · 보상 타일 4(첫 클리어 뱃지) · 별 조건 행 3 · 출정 = 붉은 Primary + 군량 비용 · 소탕 = 녹 Secondary · 닫기 버튼 삭제(PopupFill · CostOf 훅) - 거래(뽑기): 목록 바탕 · 서브탭 Round10 · 배너 아래 문양 띠 + 「픽업」 뱃지 · 천장 = 레벨형 게이지 + 노랑 배지 · 확률 = 섹션 패널 + 제목 띠 + 행 3(별 · 바 · %) · 1회 Secondary 하늘 + 보옥 비용 · 10연 Primary 노랑 + 「첫 무료」 꼬리 칩 · 각주 → ⓘ 팝업 - UiKit 공용 부품 ②: At · SkinBtn · BtnCost · SubTab/SetSubTab · Gauge/SetGauge · InfoChip · QtyChip · RewardTile · CondRow · SubTitle - 테마 행 추가(ui_theme.csv): 버튼 btn_l_yellow·btn_l_red · 소제목 선 · 큰 별 · 뱃지 · 배너 문양 · 상자 색(구 TreasureScreen.ChestColor 상수 이관 준비) 등 - 테스트 117/117 · console error 0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 09:03:43 +00:00
popupField = field.rectTransform;
popupGo = TKS.OutGame.UiKit.SkinBtn(panel.transform, "Go", "btn_l_red", UISkin.Col("red", new Color(0.89f, 0.33f, 0.23f)), "출정", 46, Color.white, 240f, PopupBtnY, 420f, 104f, ConfirmPopup);
popupGoLabel = TKS.OutGame.UiKit.LabelOf(popupGo);
popupCost = TKS.OutGame.UiKit.BtnCost(popupGo, "cur_stamina", "", 44f, 38);
popupSweep = TKS.OutGame.UiKit.SkinBtn(panel.transform, "Sweep", "btn_s_green", Color.white, "소탕", 40, Color.white, 90f, PopupBtnY + 4f, 280f, 100f, OnSweepClicked);
popupSweepLabel = TKS.OutGame.UiKit.LabelOf(popupSweep);
popupSweep.gameObject.SetActive(false);
popup.SetActive(false);
return;
}
UI 리뉴얼 A-2~A-4 화면 적용(PD #1100) — 팩 부품 + UI 테마(id 치환) · 화면 10종 · 인박스 ui kind - 테마: SOT Assets/Data/UI/ui_theme.csv(색 57 · 스킨 32 · 아이콘 63 · 제목 폰트) → 메뉴 TKS/Import UI Theme → Resources/UI/UITheme.asset (Runtime/UI/UITheme · UISkin · Editor/UIThemeImporter · ProjectSetup 에서도 임포트) · 화면 코드는 id 로만 묻는다(스프라이트 경로 0) - 신규 제작(B) 치환: Assets/UI/Samguk/**/<id>.png → 임포트 시 같은 id 스킨·아이콘 자동 치환(팩 보존 · 새 id = 아이콘 추가) · Tools/apply_delivery.py ui kind(md5 → Samguk/<group> · gim_* → Resources/Gimmicks/Art · ui_delivered.csv) - 공통: UiKit(카드 = BorderFrame_Round20 틴트 · 버튼 = Button01_s + 광택 · 원 · 진행 바 = Slider_Basic01 · 초상 틀 · 등급 칸 ItemFrame02 · 별 줄 · 병종 배지) · 재화 바(ResourceBar + cur_* 아이콘) · 하단 탭(선택 판 + PictoIcon) · 제목 띠 · 팝업(Popup Topber + 닫기 X) · 토스트 - 화면: 로비(키아트 04 배경 위쪽 ×1.22 · 출정·편성·연무장 아이콘) · 영웅(등급 칸 + 장비 아이콘 · 체크/알림 점 · 별 아이콘) · 편성 · 거래(배너 · 상자 아이콘) · 보물(상자 아이콘 · 포인트 배지) · 내정(보상 줄 · 도면·골드 아이콘) · 연무장 · 결과(리본 · 별) · 월드맵 스테이지 팝업만 팩(거점 kit 유지) - 전투: HUD 칩 · 턴 띠 · 원형 스킬 버튼 + 쿨 라디얼 · 유닛 체력 바 · 기믹 내구 핍 = 팩 슬라이더(월드 9-slice 사본 · 가운데 2 px) · 조준선 색 유지 - 3:4(1536×2048): 본문 비율 축소(UiFitHeight · 1080×1920 = 그대로) - 검증: 플레이모드 116/116(기존 115 + UIThemeTests 1) · 컴파일 0 · error 0 · 캡처 = DataImporter.CaptureUI(UICaptureDriver · 15장) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 14:20:57 +00:00
popupGo = WideButton("Go", panel.transform, "출전", new Vector2(-180f, 80f), UISkin.Col("red", new Color(0.89f, 0.33f, 0.23f)), ConfirmPopup, out popupGoLabel);
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
Text closeLabel;
UI 리뉴얼 A-2~A-4 화면 적용(PD #1100) — 팩 부품 + UI 테마(id 치환) · 화면 10종 · 인박스 ui kind - 테마: SOT Assets/Data/UI/ui_theme.csv(색 57 · 스킨 32 · 아이콘 63 · 제목 폰트) → 메뉴 TKS/Import UI Theme → Resources/UI/UITheme.asset (Runtime/UI/UITheme · UISkin · Editor/UIThemeImporter · ProjectSetup 에서도 임포트) · 화면 코드는 id 로만 묻는다(스프라이트 경로 0) - 신규 제작(B) 치환: Assets/UI/Samguk/**/<id>.png → 임포트 시 같은 id 스킨·아이콘 자동 치환(팩 보존 · 새 id = 아이콘 추가) · Tools/apply_delivery.py ui kind(md5 → Samguk/<group> · gim_* → Resources/Gimmicks/Art · ui_delivered.csv) - 공통: UiKit(카드 = BorderFrame_Round20 틴트 · 버튼 = Button01_s + 광택 · 원 · 진행 바 = Slider_Basic01 · 초상 틀 · 등급 칸 ItemFrame02 · 별 줄 · 병종 배지) · 재화 바(ResourceBar + cur_* 아이콘) · 하단 탭(선택 판 + PictoIcon) · 제목 띠 · 팝업(Popup Topber + 닫기 X) · 토스트 - 화면: 로비(키아트 04 배경 위쪽 ×1.22 · 출정·편성·연무장 아이콘) · 영웅(등급 칸 + 장비 아이콘 · 체크/알림 점 · 별 아이콘) · 편성 · 거래(배너 · 상자 아이콘) · 보물(상자 아이콘 · 포인트 배지) · 내정(보상 줄 · 도면·골드 아이콘) · 연무장 · 결과(리본 · 별) · 월드맵 스테이지 팝업만 팩(거점 kit 유지) - 전투: HUD 칩 · 턴 띠 · 원형 스킬 버튼 + 쿨 라디얼 · 유닛 체력 바 · 기믹 내구 핍 = 팩 슬라이더(월드 9-slice 사본 · 가운데 2 px) · 조준선 색 유지 - 3:4(1536×2048): 본문 비율 축소(UiFitHeight · 1080×1920 = 그대로) - 검증: 플레이모드 116/116(기존 115 + UIThemeTests 1) · 컴파일 0 · error 0 · 캡처 = DataImporter.CaptureUI(UICaptureDriver · 15장) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 14:20:57 +00:00
WideButton("Close", panel.transform, "닫기", new Vector2(180f, 80f), UISkin.Col("dark", new Color(0.6f, 0.55f, 0.5f)), ClosePopup, out closeLabel);
popupSweep = WideButton("Sweep", panel.transform, "소탕", new Vector2(0f, 200f), UISkin.Col("ok", new Color(0.35f, 0.5f, 0.35f)), OnSweepClicked, out popupSweepLabel);
아웃게임 1차(PD #1093 세션 A) — 본영 로비 · 세이브 · 군량 · 영웅(레벨·승급 6칸·진화·스킬 표시) · 편성(전열 3/후열 2 · 프리셋 3) · 거래(뽑기·골드 장비 상점) · 스테이지 보상·별 3·소탕 - 데이터: 기획 tables/ 12장 → Assets/Data/OutGame/*.csv · 메뉴 TKS/Import OutGame Data(Editor/DataImporter) → Resources/OutGame 9 자산(HeroDb·GearDb·GachaConfig·EconomyConfig·RewardTable·LevelTable·PromotionTable·EvolveTable·SkillInfoDb) · 검증(행 수·필수 열·id 유일·hero↔skill↔gear·확률 합) 오류 시 자산 불변 · BalanceConfig.heroes[]/HeroDef 삭제 → HeroDb(기존 5인 id 유지) · economy.csv 키 17 + gacha.csv 키 2 추가(기획서 본문 값 · C45) - 세이브: persistentDataPath/save.json · ver 1 · 즉시 저장 · 오프라인 군량 회복 · 일일 초기화 · 신규 유저 = 유비·관우·장비·조운·황충 Lv1 녹 ★=희귀도 · 골드 1000 · 보옥 300 · 군량 30 · 테스트·캡처 = 메모리 전용 - 화면(uGUI 와이어프레임 · img03·06·08·11): 시작 = 본영 로비(출정 → 월드맵 · 편성 · 연무장/보물/내정 준비 중 · 동맹 추후) · 재화 바(월드맵 포함 · 군량 타이머) · 하단 탭 5 · ◀/Esc 일관 · 영웅 목록·상세·상세정보·도감 · 편성(탭·드래그) · 뽑기(천장 n/80 · 확률 공개 · 첫 10연 무료 · 10연 ★★ 보장 · 카드 순차 공개) · 장비 상점(흰/녹 6종 일일 · sell×5 · 새로고침 보옥 20) - 전투 연결: BattleManager.LineupProvider/Deployed(LineupEntry · §3-2 스탯 · 방어 배율 생성 뒤) · playerSpawnPoints = 전열 (−4/0/4, −12) · 후열 (−2/2, −14) · WorldMapScreen 훅(팝업 군량·보상·별 · 입장 군량 · 노드 별 star_on/off · 소탕 · ◀ 본영 · TopInset) · 결과 패널(별 3 조건 · 골드·경험·보옥·장비) · GameBootstrap/AutoPlayDriver 로비 시작 - B 세션 파일(ActionResolver·Combat·UnitView·BattleHUD·SlingshotInput·EnemyAI) 미변경 - 테스트 56/56(기존 41 유지 · 신규 OutGameTests 15) · console error 0 · 사본 GUI 캡처 11장(DataImporter.CaptureOutGame) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:11:10 +00:00
popupSweep.gameObject.SetActive(false);
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
popup.SetActive(false);
}
// ---------- 그리기 도우미 ----------
void Update()
{
if (cursor != null) cursor.anchoredPosition = cursorBase + new Vector2(0f, 10f * Mathf.Abs(Mathf.Sin(Time.unscaledTime * 4f)));
bool interact = Time.unscaledTime >= inputBlockUntil;
if (group != null && group.interactable != interact) group.interactable = interact; // 바뀔 때만(버튼 색 전환 → 재구성 방지)
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
}
static Vector2 V(float[] a)
{
return a != null && a.Length >= 2 ? new Vector2(a[0], a[1]) : Vector2.zero;
}
static Sprite Sprite(string name)
{
return Resources.Load<Sprite>(UiRoot + name);
}
/// <summary>맵 px 위치(y 아래로)에 부품 1개. 크기 = kit refSize · 피벗 = kit pivot.</summary>
Image Piece(string name, Vector2 mapPos, bool raycast)
{
var sp = Sprite(name);
var kit = data.Kit(name);
if (sp == null || kit == null) return null;
var go = new GameObject(name);
go.transform.SetParent(content, false);
var rt = go.AddComponent<RectTransform>();
rt.anchorMin = rt.anchorMax = new Vector2(0f, 1f);
rt.pivot = new Vector2(kit.pivot[0], 1f - kit.pivot[1]);
rt.sizeDelta = new Vector2(kit.refSize[0], kit.refSize[1]);
rt.anchoredPosition = new Vector2(mapPos.x, -mapPos.y);
var img = go.AddComponent<Image>();
img.sprite = sp;
img.raycastTarget = raycast;
spawned.Add(go);
return img;
}
static RectTransform Rect(string name, Transform parent, Vector2 aMin, Vector2 aMax, Vector2 pivot, Vector2 pos, Vector2 size)
{
var go = new GameObject(name);
go.transform.SetParent(parent, false);
var rt = go.AddComponent<RectTransform>();
rt.anchorMin = aMin;
rt.anchorMax = aMax;
rt.pivot = pivot;
rt.anchoredPosition = pos;
rt.sizeDelta = size;
return rt;
}
static Image Img(string name, Transform parent, Sprite sp, Vector2 aMin, Vector2 aMax, Vector2 pivot, Vector2 pos, Vector2 size)
{
var rt = Rect(name, parent, aMin, aMax, pivot, pos, size);
var img = rt.gameObject.AddComponent<Image>();
img.sprite = sp;
img.raycastTarget = false;
return img;
}
/// <summary>부모 안 anchor 지점(비율 · 아래 원점)에 가운데 맞춤 글자(흰 글자 + 검정 테).</summary>
static Text Label(Transform parent, string text, int size, Color color, Vector2 anchor)
{
var rt = Rect("Text", parent, anchor, anchor, new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(600f, size * 2.6f));
var t = rt.gameObject.AddComponent<Text>();
t.font = TextUtil.Font;
t.fontSize = size;
t.fontStyle = FontStyle.Bold;
t.alignment = TextAnchor.MiddleCenter;
t.color = color;
t.horizontalOverflow = HorizontalWrapMode.Overflow;
t.verticalOverflow = VerticalWrapMode.Overflow;
t.raycastTarget = false;
t.text = text;
var o = rt.gameObject.AddComponent<Outline>();
o.effectColor = Ink;
o.effectDistance = new Vector2(3f, -3f);
return t;
}
Button SmallButton(string name, Transform parent, string label, Vector2 anchor, Vector2 pos, Action onClick)
{
var img = Img(name, parent, Sprite("plate"), anchor, anchor, new Vector2(0.5f, 0.5f), pos, new Vector2(110f, 80f));
img.type = Image.Type.Sliced;
img.raycastTarget = true;
var b = img.gameObject.AddComponent<Button>();
b.onClick.AddListener(() => onClick());
var t = Label(img.transform, label, 40, new Color(0.45f, 0.22f, 0.12f), new Vector2(0.5f, 0.55f));
t.GetComponent<Outline>().enabled = false;
return b;
}
Button WideButton(string name, Transform parent, string label, Vector2 pos, Color tint, Action onClick, out Text labelText)
{
var img = Img(name, parent, Sprite("plate"), new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0.5f, 0.5f), pos, new Vector2(300f, 100f));
img.type = Image.Type.Sliced;
UI 리뉴얼 A-2~A-4 화면 적용(PD #1100) — 팩 부품 + UI 테마(id 치환) · 화면 10종 · 인박스 ui kind - 테마: SOT Assets/Data/UI/ui_theme.csv(색 57 · 스킨 32 · 아이콘 63 · 제목 폰트) → 메뉴 TKS/Import UI Theme → Resources/UI/UITheme.asset (Runtime/UI/UITheme · UISkin · Editor/UIThemeImporter · ProjectSetup 에서도 임포트) · 화면 코드는 id 로만 묻는다(스프라이트 경로 0) - 신규 제작(B) 치환: Assets/UI/Samguk/**/<id>.png → 임포트 시 같은 id 스킨·아이콘 자동 치환(팩 보존 · 새 id = 아이콘 추가) · Tools/apply_delivery.py ui kind(md5 → Samguk/<group> · gim_* → Resources/Gimmicks/Art · ui_delivered.csv) - 공통: UiKit(카드 = BorderFrame_Round20 틴트 · 버튼 = Button01_s + 광택 · 원 · 진행 바 = Slider_Basic01 · 초상 틀 · 등급 칸 ItemFrame02 · 별 줄 · 병종 배지) · 재화 바(ResourceBar + cur_* 아이콘) · 하단 탭(선택 판 + PictoIcon) · 제목 띠 · 팝업(Popup Topber + 닫기 X) · 토스트 - 화면: 로비(키아트 04 배경 위쪽 ×1.22 · 출정·편성·연무장 아이콘) · 영웅(등급 칸 + 장비 아이콘 · 체크/알림 점 · 별 아이콘) · 편성 · 거래(배너 · 상자 아이콘) · 보물(상자 아이콘 · 포인트 배지) · 내정(보상 줄 · 도면·골드 아이콘) · 연무장 · 결과(리본 · 별) · 월드맵 스테이지 팝업만 팩(거점 kit 유지) - 전투: HUD 칩 · 턴 띠 · 원형 스킬 버튼 + 쿨 라디얼 · 유닛 체력 바 · 기믹 내구 핍 = 팩 슬라이더(월드 9-slice 사본 · 가운데 2 px) · 조준선 색 유지 - 3:4(1536×2048): 본문 비율 축소(UiFitHeight · 1080×1920 = 그대로) - 검증: 플레이모드 116/116(기존 115 + UIThemeTests 1) · 컴파일 0 · error 0 · 캡처 = DataImporter.CaptureUI(UICaptureDriver · 15장) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 14:20:57 +00:00
bool pack = UISkin.Apply(img, "button");
if (pack) img.rectTransform.sizeDelta = new Vector2(320f, 112f);
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
img.color = tint;
img.raycastTarget = true;
var b = img.gameObject.AddComponent<Button>();
b.onClick.AddListener(() => onClick());
UI 리뉴얼 A-2~A-4 화면 적용(PD #1100) — 팩 부품 + UI 테마(id 치환) · 화면 10종 · 인박스 ui kind - 테마: SOT Assets/Data/UI/ui_theme.csv(색 57 · 스킨 32 · 아이콘 63 · 제목 폰트) → 메뉴 TKS/Import UI Theme → Resources/UI/UITheme.asset (Runtime/UI/UITheme · UISkin · Editor/UIThemeImporter · ProjectSetup 에서도 임포트) · 화면 코드는 id 로만 묻는다(스프라이트 경로 0) - 신규 제작(B) 치환: Assets/UI/Samguk/**/<id>.png → 임포트 시 같은 id 스킨·아이콘 자동 치환(팩 보존 · 새 id = 아이콘 추가) · Tools/apply_delivery.py ui kind(md5 → Samguk/<group> · gim_* → Resources/Gimmicks/Art · ui_delivered.csv) - 공통: UiKit(카드 = BorderFrame_Round20 틴트 · 버튼 = Button01_s + 광택 · 원 · 진행 바 = Slider_Basic01 · 초상 틀 · 등급 칸 ItemFrame02 · 별 줄 · 병종 배지) · 재화 바(ResourceBar + cur_* 아이콘) · 하단 탭(선택 판 + PictoIcon) · 제목 띠 · 팝업(Popup Topber + 닫기 X) · 토스트 - 화면: 로비(키아트 04 배경 위쪽 ×1.22 · 출정·편성·연무장 아이콘) · 영웅(등급 칸 + 장비 아이콘 · 체크/알림 점 · 별 아이콘) · 편성 · 거래(배너 · 상자 아이콘) · 보물(상자 아이콘 · 포인트 배지) · 내정(보상 줄 · 도면·골드 아이콘) · 연무장 · 결과(리본 · 별) · 월드맵 스테이지 팝업만 팩(거점 kit 유지) - 전투: HUD 칩 · 턴 띠 · 원형 스킬 버튼 + 쿨 라디얼 · 유닛 체력 바 · 기믹 내구 핍 = 팩 슬라이더(월드 9-slice 사본 · 가운데 2 px) · 조준선 색 유지 - 3:4(1536×2048): 본문 비율 축소(UiFitHeight · 1080×1920 = 그대로) - 검증: 플레이모드 116/116(기존 115 + UIThemeTests 1) · 컴파일 0 · error 0 · 캡처 = DataImporter.CaptureUI(UICaptureDriver · 15장) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 14:20:57 +00:00
labelText = Label(img.transform, label, 42, pack ? Color.white : Paper, new Vector2(0.5f, pack ? 0.6f : 0.55f));
if (pack)
{
labelText.font = UISkin.TitleFont;
labelText.GetComponent<Outline>().effectColor = UISkin.Col("stroke", Ink);
}
시작 화면 = 챕터 월드맵(스크롤 2160×3840 · 10장) → 스테이지 팝업(임시) → 전투 → 결과 탭 = 맵 복귀·다음 노드 열림 + 아군 뒷모습·황건적·동탁군 포즈 반영 (PD 2026-11-05) - WorldMapScreen(신규): ScrollRect 맵 · 길 따라 깃발 노드(open/clear/lock · 보스) · 길 점 · 현재 위치 핀 · 챕터 띠 ◀▶ · 스테이지 팝업(적 구성·보스 · 출전/닫기) · 임시 진행도(메모리) - 데이터 = Resources/ChapterMap/Data/world.json(원화 세션 chap_install.py 생성 · 맵 크기·실제 길·부품 크기/피벗/번호 자리·임시 스테이지 연결 = 챕터당 10노드 · 전투 = 기존 스테이지 0/1/2) · 지명판 = 끔(생성 그림과 위치 어긋남) - GameBootstrap: StartOnWorldMap(기본 true) · BattleManager: ResultHandler · GoIdle · BattleHUD 결과 문구 · AutoPlayDriver: 월드맵·팝업 캡처 후 1-1 출전 - UnitArtImporter: ChapterMap/Maps(4096 · 압축) · ChapterMap/UI(import.json 피벗·9-slice·PPU 133.33) - 유닛: 아군 5인 앞·뒤 × idle/ready/action(키아트 세션 · md5 30/30) · 황건적 5 = 인박스 20261105_0312_hgj(QA PASS · md5 15/15) · 동탁군 5(여포 포함 · 원화 세션 poses md5 15/15 · PD 지시로 직접 반영) - 테스트 27/27(+ 월드맵 시작 · 팝업→전투→맵 복귀 · 맵/UI 리소스 · 포즈 세트·동작별 스프라이트 교체 · 앞뒤 클립 고정 자료 hgj_infantry → 아군 아트) · console error 0 - 남은 것(QA r2 B 2 · PD 결정): ch04 보스 초상 틀이 위 HUD 줄 안 · ch08 경로가 다리 없는 큰길을 피해 풀밭·강둑으로 우회 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:38:47 +00:00
return b;
}
}
}