Merge remote-tracking branch 'origin/main'

This commit is contained in:
깃 관리자 2026-11-12 23:46:51 +09:00
commit 8eee0f6bb3
37 changed files with 2647 additions and 3 deletions

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: bd122d65f778f914ba5fc24acda8456f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,34 @@
n_chapter,n_stage,n_order,s_boss_id,s_title_ko,s_line_ko,Memo
1,5,1,hgj_boss_chengyuanzhi,황건 대장,부장의 원수는 내가 직접 갚아 주마!,정원지 · 1-4 에서 부장 등무가 쓰러진 직후 · 연의 1회
1,10,1,hgj_boss_zhangjiao,천공장군,창천이사 황천당립! 하늘은 우리 편이다!,장각 · 황건의 구호(蒼天已死 黃天當立) · 연의 1회
2,5,1,dz_boss_huaxiong,서량의 맹장,또 목을 내놓으러 온 놈이 있느냐!,화웅 · 유섭·반봉을 벤 뒤 관우가 나서는 장면 · 연의 5회
2,10,1,dz_boss_lvbu,천하무쌍,셋이 한꺼번에 덤벼도 상관없다!,여포 · 삼영전여포 · 연의 5회
3,5,1,ys_boss_quyi,선등 노병 대장,노병들아 활을 들어라! 한 놈도 강을 못 건넌다!,국의 · 노병 일제 사격으로 엄강을 무너뜨림 · 연의 7회
3,10,1,hgj_boss_guanhai,황건 잔당의 거한,북해성은 오늘 이 관해의 것이다!,관해 · 공융의 북해 포위 · 연의 11회
3,15,1,cc_boss_yujin,조조군 선봉장,어디서 온 미친 놈들이냐!,우금 · 기획서 3-15 컨셉의 대사 그대로 · 연의 11회
4,5,1,ysu_boss_jiling,원술군 대장,관우! 오늘은 승부를 내자!,기령 · 관우와 30합 · 연의 14회
4,10,1,dz_boss_gaoshun,함진영 대장,함진영! 한 걸음도 물러서지 마라!,고순 · 함진영(陷陣營) 지휘 · 연의 18회
4,15,1,dz_boss_lvbu,하비의 비장,이 여포는 아직 끝나지 않았다!,여포 · 배신당해 고립된 백문루 직전 · 연의 19회
5,5,1,ysu_boss_jiling,중가의 대장,우이에서 못 낸 승부 여기서 내 주마!,기령 · 4-5 관우와 비긴 기억 · 이번엔 장비가 벰 · 연의 21회
5,10,1,cc_boss_liudai,토벌군 대장,승상의 명이다! 유비를 사로잡아라!,유대 · 2인 보스 첫째 · 연의 22회
5,10,2,cc_boss_wangzhong,토벌군 부장,공은 내가 먼저 세우겠다!,왕충 · 2인 보스 둘째 · 유대와 공을 다툼 · 연의 22회
5,15,1,cc_boss_xuhuang,대부의 명장,운장 돌아갈 길은 이미 없소.,서황 · 관우와 옛 친분 · 토산 고립 · 연의 25회
5,15,2,cc_boss_xuchu,호치,이 허저를 넘어 보아라!,허저 · 2인 보스 둘째 · 연의 25회
6,5,1,ys_boss_yanliang,하북의 명장,목을 바치러 온 자가 또 있구나.,안량 · 송헌·위속을 벤 뒤의 오만 · 연의 25회
6,10,1,ys_boss_wenchou,하북의 맹장,안량의 원수 오늘 갚아 주마!,문추 · 연의 26회
6,15,1,cc_boss_bianxi,사수관 수장,들켰구나! 모두 나와 관우를 쳐라!,변희 · 오관참육장 · 진국사 매복이 드러난 순간(6-14 보정의 눈짓 뒤) · 연의 27회
6,20,1,cc_boss_xiahoudun,외눈의 장군,내 부장을 베고 어디로 가느냐!,하후돈 · 6-19 진기를 잃은 직후 · 4-9 에서 눈을 잃음 · 연의 28회·각색
7,5,1,cc_boss_caiyang,복수의 노장,진기의 원수 네 목으로 갚아라!,채양 · 생질 진기의 복수 · 연의 28회
7,10,1,cc_boss_gaolan,하북 출신 맹장,유비! 이 산길이 네 무덤이다!,고람 · 양산 패전 · 연의 31회
8,5,1,jz_boss_zhangwu,강하 반란군 대장,적로의 발굽 아래 짓밟혀라!,장무 · 명마 적로를 탄 반란군 대장 · 연의 34회
8,10,1,cc_boss_caoren,팔문금쇄진의 주인,이 진을 깨뜨릴 자가 있다면 나와 보라!,조인 · 팔문금쇄진 · 연의 36회
8,15,1,cc_boss_xiahoudun,남정군 도독,풋내기 군사 따위 단숨에 짓밟아 주마!,하후돈 · 제갈량의 첫 지휘를 얕봄 · 연의 39회
9,5,1,jz_boss_wenpin,양양의 수문장,양양의 문은 결코 열리지 않는다!,문빙 · 유종의 거부 · 연의 41회
9,10,1,cc_boss_zhanghe,오자양장,승상께서 산 채로 잡으라 하셨다!,장합 · 조조의 「산 채로 잡아라」 · 연의 41회
9,15,1,cc_boss_caocao,한의 승상,또 제갈량의 계략인가...!,조조 · 기획서 9-15 컨셉의 대사 그대로 · 연의 42회·각색
10,5,1,jz_boss_caimao,형주 수군 도독,물 위의 싸움은 우리가 한 수 위다!,채모 · 2인 보스 첫째 · 연의 45회
10,5,2,jz_boss_zhangyun,형주 수군 부도독,배를 붙여라! 한 척도 놓치지 마라!,장윤 · 2인 보스 둘째 · 연의 45회
10,10,1,cc_boss_yujin,연환선단 도독,사슬로 묶은 배는 땅과 같다!,우금 · 연환계 함대 · 연의 45회(배경)·각색
10,10,2,cc_boss_maojie,연환선단 부도독,궁수대! 화살을 아끼지 마라!,모개 · 2인 보스 둘째(궁병) · 연의 45회(배경)·각색
10,15,1,dz_boss_zhangliao,조조의 호위 장수,승상! 제 뒤로 오십시오!,장료 · 조조를 태우고 북안으로 · 연의 49회
10,20,1,cc_boss_caocao,패주하는 승상,운장... 옛정을 잊지는 않았겠지?,조조 · 화용도 의석조조 · 연의 50회
1 n_chapter n_stage n_order s_boss_id s_title_ko s_line_ko Memo
2 1 5 1 hgj_boss_chengyuanzhi 황건 대장 부장의 원수는 내가 직접 갚아 주마! 정원지 · 1-4 에서 부장 등무가 쓰러진 직후 · 연의 1회
3 1 10 1 hgj_boss_zhangjiao 천공장군 창천이사 황천당립! 하늘은 우리 편이다! 장각 · 황건의 구호(蒼天已死 黃天當立) · 연의 1회
4 2 5 1 dz_boss_huaxiong 서량의 맹장 또 목을 내놓으러 온 놈이 있느냐! 화웅 · 유섭·반봉을 벤 뒤 관우가 나서는 장면 · 연의 5회
5 2 10 1 dz_boss_lvbu 천하무쌍 셋이 한꺼번에 덤벼도 상관없다! 여포 · 삼영전여포 · 연의 5회
6 3 5 1 ys_boss_quyi 선등 노병 대장 노병들아 활을 들어라! 한 놈도 강을 못 건넌다! 국의 · 노병 일제 사격으로 엄강을 무너뜨림 · 연의 7회
7 3 10 1 hgj_boss_guanhai 황건 잔당의 거한 북해성은 오늘 이 관해의 것이다! 관해 · 공융의 북해 포위 · 연의 11회
8 3 15 1 cc_boss_yujin 조조군 선봉장 어디서 온 미친 놈들이냐! 우금 · 기획서 3-15 컨셉의 대사 그대로 · 연의 11회
9 4 5 1 ysu_boss_jiling 원술군 대장 관우! 오늘은 승부를 내자! 기령 · 관우와 30합 · 연의 14회
10 4 10 1 dz_boss_gaoshun 함진영 대장 함진영! 한 걸음도 물러서지 마라! 고순 · 함진영(陷陣營) 지휘 · 연의 18회
11 4 15 1 dz_boss_lvbu 하비의 비장 이 여포는 아직 끝나지 않았다! 여포 · 배신당해 고립된 백문루 직전 · 연의 19회
12 5 5 1 ysu_boss_jiling 중가의 대장 우이에서 못 낸 승부 여기서 내 주마! 기령 · 4-5 관우와 비긴 기억 · 이번엔 장비가 벰 · 연의 21회
13 5 10 1 cc_boss_liudai 토벌군 대장 승상의 명이다! 유비를 사로잡아라! 유대 · 2인 보스 첫째 · 연의 22회
14 5 10 2 cc_boss_wangzhong 토벌군 부장 공은 내가 먼저 세우겠다! 왕충 · 2인 보스 둘째 · 유대와 공을 다툼 · 연의 22회
15 5 15 1 cc_boss_xuhuang 대부의 명장 운장 돌아갈 길은 이미 없소. 서황 · 관우와 옛 친분 · 토산 고립 · 연의 25회
16 5 15 2 cc_boss_xuchu 호치 이 허저를 넘어 보아라! 허저 · 2인 보스 둘째 · 연의 25회
17 6 5 1 ys_boss_yanliang 하북의 명장 목을 바치러 온 자가 또 있구나. 안량 · 송헌·위속을 벤 뒤의 오만 · 연의 25회
18 6 10 1 ys_boss_wenchou 하북의 맹장 안량의 원수 오늘 갚아 주마! 문추 · 연의 26회
19 6 15 1 cc_boss_bianxi 사수관 수장 들켰구나! 모두 나와 관우를 쳐라! 변희 · 오관참육장 · 진국사 매복이 드러난 순간(6-14 보정의 눈짓 뒤) · 연의 27회
20 6 20 1 cc_boss_xiahoudun 외눈의 장군 내 부장을 베고 어디로 가느냐! 하후돈 · 6-19 진기를 잃은 직후 · 4-9 에서 눈을 잃음 · 연의 28회·각색
21 7 5 1 cc_boss_caiyang 복수의 노장 진기의 원수 네 목으로 갚아라! 채양 · 생질 진기의 복수 · 연의 28회
22 7 10 1 cc_boss_gaolan 하북 출신 맹장 유비! 이 산길이 네 무덤이다! 고람 · 양산 패전 · 연의 31회
23 8 5 1 jz_boss_zhangwu 강하 반란군 대장 적로의 발굽 아래 짓밟혀라! 장무 · 명마 적로를 탄 반란군 대장 · 연의 34회
24 8 10 1 cc_boss_caoren 팔문금쇄진의 주인 이 진을 깨뜨릴 자가 있다면 나와 보라! 조인 · 팔문금쇄진 · 연의 36회
25 8 15 1 cc_boss_xiahoudun 남정군 도독 풋내기 군사 따위 단숨에 짓밟아 주마! 하후돈 · 제갈량의 첫 지휘를 얕봄 · 연의 39회
26 9 5 1 jz_boss_wenpin 양양의 수문장 양양의 문은 결코 열리지 않는다! 문빙 · 유종의 거부 · 연의 41회
27 9 10 1 cc_boss_zhanghe 오자양장 승상께서 산 채로 잡으라 하셨다! 장합 · 조조의 「산 채로 잡아라」 · 연의 41회
28 9 15 1 cc_boss_caocao 한의 승상 또 제갈량의 계략인가...! 조조 · 기획서 9-15 컨셉의 대사 그대로 · 연의 42회·각색
29 10 5 1 jz_boss_caimao 형주 수군 도독 물 위의 싸움은 우리가 한 수 위다! 채모 · 2인 보스 첫째 · 연의 45회
30 10 5 2 jz_boss_zhangyun 형주 수군 부도독 배를 붙여라! 한 척도 놓치지 마라! 장윤 · 2인 보스 둘째 · 연의 45회
31 10 10 1 cc_boss_yujin 연환선단 도독 사슬로 묶은 배는 땅과 같다! 우금 · 연환계 함대 · 연의 45회(배경)·각색
32 10 10 2 cc_boss_maojie 연환선단 부도독 궁수대! 화살을 아끼지 마라! 모개 · 2인 보스 둘째(궁병) · 연의 45회(배경)·각색
33 10 15 1 dz_boss_zhangliao 조조의 호위 장수 승상! 제 뒤로 오십시오! 장료 · 조조를 태우고 북안으로 · 연의 49회
34 10 20 1 cc_boss_caocao 패주하는 승상 운장... 옛정을 잊지는 않았겠지? 조조 · 화용도 의석조조 · 연의 50회

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 12ea679cb7e96644ea7a143210f60457
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,33 @@
s_key,f_value,Memo
warn_sec,0.4,① 경고 예고 — 붉은 가장자리 깜빡임 + 위아래 검은 띠가 들어오는 시간(초)
warn_blink_count,2,① 붉은 가장자리 깜빡임 횟수(정수)
letterbox_ratio,0.08,① 위아래 검은 띠 높이(화면 높이 비율)
focus_move_sec,0.8,② 카메라가 아군 쪽에서 보스로 이동·확대하는 시간(초 · 지금 FocusOn·ZoomTo 는 시간 인자가 없어 시간 지정 버전 필요)
focus_view_ratio,0.6,② 보스 포커스 때 시야 높이(평소 시야 높이 대비 비율 · 작을수록 확대)
dim_others,0.4,② 포커스 중 보스 외 유닛 어둡게(0 = 그대로 · 1 = 검정)
focus_ring_scale,1.6,② 보스 발밑 붉은 원 지름(보스 지름 대비 배율)
cutin_banner_in_sec,0.2,③ 「BOSS 등장!」 띠가 왼쪽 위 화면 밖에서 쓸고 들어오는 시간(초 · 컷인 맨 먼저)
cutin_banner_pop_scale,1.35,③ 「BOSS 등장!」 글자가 크게 찍혔다 제자리로 줄어드는 시작 배율(→ 1.0)
cutin_banner_text_width,0.6,③ 「BOSS 등장!」 글자 너비(화면 폭 비율)
cutin_info_delay_sec,0.15,③ 위 띠가 자리 잡은 뒤 보스 그림·아래 이름 띠가 들어오기까지(초)
cutin_in_sec,0.25,③ 보스 그림(오른쪽에서)·아래 이름 띠가 들어오는 시간(초)
cutin_hold_sec,0.8,③ 다 들어온 뒤 멈춰 있는 시간(초) · 컷인 전체 = 위 띠 + 지연 + 들어옴 + 멈춤 + 빠짐 = 1.7초
cutin_out_sec,0.3,③ 컷인이 빠지는 시간(초)
cutin_bg_dark,0.55,③ 컷인 뒤 전장 어둡게(0~1)
cutin_art_height,0.55,③ 보스 전신 그림 높이(화면 높이 비율 · 1인 보스)
cutin_art_height_duo,0.45,③ 2인 보스일 때 그림 높이(각자 · 화면 높이 비율)
cutin_band_angle,12,③ 위·아래 띠 기울기(도 · 오른쪽 위로)
cutin_shake,0.25,③ 보스 그림이 멈출 때 화면 흔들림 세기(CameraController.Shake 의 magnitude)
cutin_shake_sec,0.25,③ 그 흔들림 시간(초 · Shake 의 duration)
bubble_pop_sec,0.15,④ 말풍선이 튀어나오는 시간(초)
bubble_pop_from,0.6,④ 튀어나올 때 시작 크기(배)
bubble_pop_peak,1.05,④ 튀어나올 때 가장 커지는 크기(배 · 그 뒤 1.0)
bubble_char_per_sec,30,④ 대사 글자가 찍히는 속도(초당 글자)
bubble_hold_sec,1.3,④ 대사가 다 찍힌 뒤 유지 시간(초)
bubble_fade_sec,0.2,④ 말풍선이 사라지는 시간(초)
bubble_max_chars,28,④ 대사 최대 글자 수(정수 · 공백 포함 · 넘으면 데이터 검사 실패)
bubble_font_size,30,④ 말풍선 글자 크기(px · 1080×1920 기준)
second_boss_move_sec,0.5,④ 2인 보스일 때 첫째 → 둘째 보스로 카메라 이동 시간(초)
return_sec,0.7,⑤ 보스에서 아군 쪽 기본 시야로 돌아오는 시간(초)
skip_show_after_sec,0.5,건너뛰기 버튼이 나타나는 시점(연출 시작 후 초)
replay_mode,1,다시 출정(클리어 후) 때 연출 — 정수 코드 0 = 전체 · 1 = 축약(컷인 빼고 포커스 + 말풍선) · 2 = 없음
1 s_key f_value Memo
2 warn_sec 0.4 ① 경고 예고 — 붉은 가장자리 깜빡임 + 위아래 검은 띠가 들어오는 시간(초)
3 warn_blink_count 2 ① 붉은 가장자리 깜빡임 횟수(정수)
4 letterbox_ratio 0.08 ① 위아래 검은 띠 높이(화면 높이 비율)
5 focus_move_sec 0.8 ② 카메라가 아군 쪽에서 보스로 이동·확대하는 시간(초 · 지금 FocusOn·ZoomTo 는 시간 인자가 없어 시간 지정 버전 필요)
6 focus_view_ratio 0.6 ② 보스 포커스 때 시야 높이(평소 시야 높이 대비 비율 · 작을수록 확대)
7 dim_others 0.4 ② 포커스 중 보스 외 유닛 어둡게(0 = 그대로 · 1 = 검정)
8 focus_ring_scale 1.6 ② 보스 발밑 붉은 원 지름(보스 지름 대비 배율)
9 cutin_banner_in_sec 0.2 ③ 「BOSS 등장!」 띠가 왼쪽 위 화면 밖에서 쓸고 들어오는 시간(초 · 컷인 맨 먼저)
10 cutin_banner_pop_scale 1.35 ③ 「BOSS 등장!」 글자가 크게 찍혔다 제자리로 줄어드는 시작 배율(→ 1.0)
11 cutin_banner_text_width 0.6 ③ 「BOSS 등장!」 글자 너비(화면 폭 비율)
12 cutin_info_delay_sec 0.15 ③ 위 띠가 자리 잡은 뒤 보스 그림·아래 이름 띠가 들어오기까지(초)
13 cutin_in_sec 0.25 ③ 보스 그림(오른쪽에서)·아래 이름 띠가 들어오는 시간(초)
14 cutin_hold_sec 0.8 ③ 다 들어온 뒤 멈춰 있는 시간(초) · 컷인 전체 = 위 띠 + 지연 + 들어옴 + 멈춤 + 빠짐 = 1.7초
15 cutin_out_sec 0.3 ③ 컷인이 빠지는 시간(초)
16 cutin_bg_dark 0.55 ③ 컷인 뒤 전장 어둡게(0~1)
17 cutin_art_height 0.55 ③ 보스 전신 그림 높이(화면 높이 비율 · 1인 보스)
18 cutin_art_height_duo 0.45 ③ 2인 보스일 때 그림 높이(각자 · 화면 높이 비율)
19 cutin_band_angle 12 ③ 위·아래 띠 기울기(도 · 오른쪽 위로)
20 cutin_shake 0.25 ③ 보스 그림이 멈출 때 화면 흔들림 세기(CameraController.Shake 의 magnitude)
21 cutin_shake_sec 0.25 ③ 그 흔들림 시간(초 · Shake 의 duration)
22 bubble_pop_sec 0.15 ④ 말풍선이 튀어나오는 시간(초)
23 bubble_pop_from 0.6 ④ 튀어나올 때 시작 크기(배)
24 bubble_pop_peak 1.05 ④ 튀어나올 때 가장 커지는 크기(배 · 그 뒤 1.0)
25 bubble_char_per_sec 30 ④ 대사 글자가 찍히는 속도(초당 글자)
26 bubble_hold_sec 1.3 ④ 대사가 다 찍힌 뒤 유지 시간(초)
27 bubble_fade_sec 0.2 ④ 말풍선이 사라지는 시간(초)
28 bubble_max_chars 28 ④ 대사 최대 글자 수(정수 · 공백 포함 · 넘으면 데이터 검사 실패)
29 bubble_font_size 30 ④ 말풍선 글자 크기(px · 1080×1920 기준)
30 second_boss_move_sec 0.5 ④ 2인 보스일 때 첫째 → 둘째 보스로 카메라 이동 시간(초)
31 return_sec 0.7 ⑤ 보스에서 아군 쪽 기본 시야로 돌아오는 시간(초)
32 skip_show_after_sec 0.5 건너뛰기 버튼이 나타나는 시점(연출 시작 후 초)
33 replay_mode 1 다시 출정(클리어 후) 때 연출 — 정수 코드 0 = 전체 · 1 = 축약(컷인 빼고 포커스 + 말풍선) · 2 = 없음

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 46eef39625c15414285dcd8bfd704b2e
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -0,0 +1,181 @@
fileFormatVersion: 2
guid: 328bf19b8f9643439ee1526b359ab4bd
TextureImporter:
internalIDToNameTable:
- first:
213: -166343660977832731
second: f000_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 0
alignment: 9
spritePivot: {x: 0.50000, y: 0.50000}
spritePixelsToUnits: 100
spriteBorder: {x: 40, y: 40, z: 40, w: 40}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: iOS
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: f000_0
rect:
serializedVersion: 2
x: 19
y: 19
width: 898
height: 820
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: 9468ef1440584c74be1e3cf42154a9e8
internalID: -166343660977832731
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 7279e003311444a7876fc9eb0264e504
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,181 @@
fileFormatVersion: 2
guid: 5637bdc2b7734583ac678e860f6d8ecf
TextureImporter:
internalIDToNameTable:
- first:
213: -166343660977832731
second: f000_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 0
alignment: 9
spritePivot: {x: 0.50000, y: 1.00000}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: iOS
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: f000_0
rect:
serializedVersion: 2
x: 19
y: 19
width: 898
height: 820
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: 1ca605ff6a084a22bf2edcbf5e916908
internalID: -166343660977832731
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 4c5d156713dc4b0b971acc2893997a72
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

View File

@ -0,0 +1,181 @@
fileFormatVersion: 2
guid: edb834ba6e244c3d881d88d8c1d073e4
TextureImporter:
internalIDToNameTable:
- first:
213: -166343660977832731
second: f000_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 0
alignment: 9
spritePivot: {x: 0.50000, y: 0.00000}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: iOS
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: f000_0
rect:
serializedVersion: 2
x: 19
y: 19
width: 898
height: 820
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: 7e4707c6d78a47c28ce02ce7f5b1357e
internalID: -166343660977832731
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 7ecd8f3bae8f45ffae13ee5c7714496b
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

View File

@ -0,0 +1,181 @@
fileFormatVersion: 2
guid: f4ce6406d2144225961c64c63dcd18b2
TextureImporter:
internalIDToNameTable:
- first:
213: -166343660977832731
second: f000_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 0
alignment: 9
spritePivot: {x: 0.50000, y: 1.00000}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: iOS
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: f000_0
rect:
serializedVersion: 2
x: 19
y: 19
width: 898
height: 820
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: 4860da324e69449496ef6a4c34d8021e
internalID: -166343660977832731
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: d7a6472618374bbcbf70cf1382f8f968
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 KiB

View File

@ -0,0 +1,181 @@
fileFormatVersion: 2
guid: 7e9462d0b8ec44bbbfa2299dae7061a5
TextureImporter:
internalIDToNameTable:
- first:
213: -166343660977832731
second: f000_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 0
alignment: 9
spritePivot: {x: 0.33333, y: 0.42418}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: iOS
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: f000_0
rect:
serializedVersion: 2
x: 19
y: 19
width: 898
height: 820
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: cddc0dd883d74f15b522e51e7e145f1c
internalID: -166343660977832731
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 1717f543f2d048ea88d6ea0f79fecb60
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,181 @@
fileFormatVersion: 2
guid: b0107069f04c42d2bd6ba681827f0b40
TextureImporter:
internalIDToNameTable:
- first:
213: -166343660977832731
second: f000_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 0
alignment: 9
spritePivot: {x: 0.50000, y: 0.50000}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: iOS
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: f000_0
rect:
serializedVersion: 2
x: 19
y: 19
width: 898
height: 820
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: 610a690f68d34772b66ac2d0da50439e
internalID: -166343660977832731
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: c67a3ce1db5248e08766397fdca3ea5b
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,181 @@
fileFormatVersion: 2
guid: 67c93a2787224ffbb67e9169db9eb177
TextureImporter:
internalIDToNameTable:
- first:
213: -166343660977832731
second: f000_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 0
alignment: 9
spritePivot: {x: 0.50000, y: 0.50000}
spritePixelsToUnits: 100
spriteBorder: {x: 24, y: 24, z: 24, w: 24}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: iOS
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: f000_0
rect:
serializedVersion: 2
x: 19
y: 19
width: 898
height: 820
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: a60d1a2559ac4d4b9ab81ee9c0fb8f87
internalID: -166343660977832731
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 3a775a79c9b342c39def19b2752cc81e
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,146 @@
n_chapter,n_stage,s_desc_ko,Memo
1,1,의용군 방이 붙은 탁현 저잣거리에서 장비가 황건 앞잡이 건달들에게 둘러싸였다.,탁현 저잣거리 — 장비 구출 · 튜토리얼(조작) · 근거 연의 1회 각색(방 앞 만남 → 장비 구출)
1,2,탁현 외곽 고갯길에서 떠돌던 무사 관우가 황건 척후들에게 포위되었다.,탁현 고갯길 — 관우 구출 · 튜토리얼(아군 밀치기 · 3턴) · 근거 연의 1회 각색(주막 만남 → 관우 구출)
1,3,셋이 함께 누상촌으로 돌아가던 길에 황건 무리가 사방에서 몰려왔다.,누상촌 어귀 — 포위 돌파 · 튜토리얼(장수 스킬) · 근거 연의 1회 각색 · 클리어 뒤 도원결의
1,4,도원에서 의형제를 맺은 세 사람이 대흥산에 닿자 정원지의 부장 등무가 앞을 막았다.,대흥산 — 등무 · 엘리트 · 튜토리얼(상성) · 근거 연의 1회
1,5,부장을 잃고 분노한 정원지가 황건 5만을 이끌고 산기슭으로 몰려왔다.,대흥산 전투 — 정원지 · 보스 · 튜토리얼(보스·바위) · 근거 연의 1회
1,6,청주태수 공경의 구원 요청에 달려가니 성은 황건 포위망에 갇혀 있었다.,청주 포위망 · 일반 · 튜토리얼(보병 연쇄·목책) · 근거 연의 1회
1,7,유비가 미끼가 되어 물러나는 사이 관우와 장비는 산 뒤에 숨어 적을 기다렸다.,청주 산골 매복 · 일반 · 튜토리얼(기병 관통·함정) · 근거 연의 1회
1,8,스승 노식의 명으로 영천에 이르니 관군의 화공에 쫓긴 황건이 불길 속을 달아나고 있었다.,영천 — 불길 속 황건 · 엘리트 · 튜토리얼(창병 밀치기·불길) · 근거 연의 1회·각색(유비군 도착 전 승부가 남 · 장보의 요술은 2회 곡양 장면을 가져옴)
1,9,모함으로 압송되는 스승 노식을 뒤로하고 광종에 이르자 장량의 황건 전위가 길을 막았다.,광종 — 황건 본진 전위 · 엘리트 · 튜토리얼(궁병 사선·자유 편성) · 근거 연의 1회·각색(장량 배치)
1,10,패주하는 동탁을 구하려 세 형제는 천공장군 장각의 대군 한가운데로 뛰어들었다.,광종 결전 — 장각 · 보스 · 종합 · 근거 연의 1회·각색(연의 2회는 관군 도착 전 장각이 이미 죽은 것으로만 나옴 · 병사 = 정사 — 결말 텍스트)
2,1,18로 제후가 모인 산조 진영 주변에 동탁군 척후 기병이 어른거렸다.,산조 진영 — 동탁군 척후 · 일반 · 근거 가상
2,2,공손찬 군의 말석에 선 유비 일행은 사수관으로 향하는 산길에 올랐다.,사수관 가는 길 · 일반 · 근거 가상
2,3,손견의 선봉이 사수관에 닿자 동탁군 장수 호진이 관문 앞에 진을 쳤다.,사수관 앞 — 호진 · 엘리트 · 근거 연의 5회·각색(연의는 정보가 호진을 벰 → 결말 텍스트)
2,4,군량이 끊긴 손견의 진영에 화웅의 야습이 덮쳐 와 밤하늘이 불타올랐다.,손견 진영 야습 · 일반 · 근거 연의 5회·각색
2,5,연합의 장수들이 잇달아 쓰러지자 마궁수 관우가 데운 술을 두고 관문 앞으로 나섰다.,사수관 — 화웅 · 보스 · 근거 연의 5회
2,6,화웅을 잃은 사수관 수비대가 관문 안쪽에서 무너지기 시작했다.,사수관 함락 — 잔병 · 일반 · 근거 가상
2,7,동탁이 친히 호로관으로 나서자 서량 기병대가 연합의 앞을 막아섰다.,호로관 가는 길 — 서량 기병 · 일반 · 근거 가상
2,8,방열과 목순이 여포에게 단번에 쓰러진 호로관 앞에 다시 적이 몰려들었다.,호로관 앞 — 방열이 쓰러진 자리 · 일반 · 근거 연의 5회(배경) · 가상(전투)
2,9,공손찬마저 쫓기게 만든 여포의 철기를 끊으려 유비 일행은 관문 측면으로 돌았다.,호로관 측면 — 적토마 돌격대 · 일반 · 근거 연의 5회·각색
2,10,천하무쌍 여포가 적토마를 몰고 나오자 장비가 먼저 장팔사모를 겨눴다.,호로관 — 여포 · 보스 · 근거 연의 5회
3,1,공손찬의 원군 요청을 받은 유비 일행은 평원을 떠나 반하로 향했다.,평원 출진 — 원소군 척후 · 일반 · 근거 가상
3,2,반하에 이르자 원소군의 경계 기병과 보병이 강변 들판을 지키고 있었다.,반하 들판 · 일반 · 근거 가상
3,3,쫓기는 공손찬 앞에 백마를 탄 젊은 장수 조운이 나타나 문추를 막아섰다.,반하 다리 — 문추의 추격 · 엘리트 · 근거 연의 7회·각색(조운 단독 장면에 유비군 동참)
3,4,공손찬의 장수 엄강을 쓰러뜨린 원소군 노병이 강변에 화살비를 퍼부었다.,반하 — 엄강의 패전 · 일반 · 근거 연의 7회
3,5,선등 노병을 이끄는 국의가 직접 활을 들고 강변 진영에 버티고 섰다.,반하 — 국의 · 보스 · 근거 연의 7회
3,6,북해의 공융이 위태롭다는 소식에 길을 나서자 청주를 휩쓰는 황건 잔당이 앞을 막았다.,북해 가는 길 — 황건 잔당 · 일반 · 근거 가상
3,7,관해의 수만 대군이 공융의 북해성을 겹겹이 에워싸고 있었다.,북해 포위망 바깥 · 일반 · 근거 연의 11회
3,8,포위를 뚫고 나온 태사자와 함께 유비 일행은 성으로 가는 길을 열었다.,태사자의 돌파로 · 일반 · 근거 연의 11회
3,9,성문을 두드리는 관해의 친위 무리를 몰아내야 북해를 구할 수 있었다.,북해 성문 — 관해 친위 · 일반 · 근거 가상
3,10,황건 잔당의 거한 관해가 큰 칼을 들고 성문 앞에 버티고 섰다.,북해 — 관해 · 보스 · 근거 연의 11회
3,11,부친의 원수를 갚겠다는 조조군이 서주의 마을들을 불태우고 있었다.,서주 가는 길 — 불타는 마을 · 일반 · 근거 연의 10회(배경)·가상
3,12,공손찬에게 빌린 조운과 함께 유비 일행은 서주를 둘러싼 조조의 포위진에 닿았다.,서주 외곽 — 조조 포위진 · 일반 · 근거 연의 11회
3,13,조조군 약탈대에 쫓기는 피난민 행렬이 서주 남쪽 들판을 메우고 있었다.,서주 남쪽 — 피난민 행렬 · 일반 · 근거 가상
3,14,유비와 장비는 1천 군사로 조조 진영의 가장자리를 뚫고 들어갔다.,조조 진영 외곽 · 일반 · 근거 연의 11회
3,15,조조 진영을 돌파하려는 유비 일행 앞에 조조의 장수 우금이 막아섰다.,서주 — 우금 · 보스 · 근거 연의 11회
4,1,서주를 노리는 원술의 대군을 막으려 유비 일행은 회수 가의 우이로 나아갔다.,우이 들판 — 원술군 선봉 · 일반 · 근거 연의 14회(배경)·가상
4,2,원술군의 군량선이 회음 강변을 따라 올라오고 있었다.,회음 강변 — 군량 수송대 · 일반 · 근거 가상
4,3,기령의 부장 순정이 관우를 노리고 진 앞으로 뛰쳐나왔다.,우이 — 순정 · 엘리트 · 근거 연의 14회
4,4,유비 일행은 밤을 틈타 기령의 진영을 덮치기로 했다.,우이 진영 야습 · 일반 · 근거 가상
4,5,원술군 대장 기령이 삼첨도를 들고 관우와 맞서러 나왔다.,우이 — 기령 · 보스 · 근거 연의 14회
4,6,장비에게 매를 맞은 조표가 성문을 열자 여포의 기병이 서주성으로 들이쳤다.,서주성의 밤 — 조표의 배신 · 일반 · 근거 연의 14회(정사는 하비)
4,7,장비가 여포의 말을 빼앗은 일로 화가 난 여포가 소패로 군을 몰아왔다.,소패 — 빼앗긴 말 · 일반 · 근거 연의 16회
4,8,소패를 잃은 유비 일행은 허도의 조조에게 몸을 맡기려 서쪽으로 달렸다.,소패 탈출 — 여포군 추격 · 일반 · 근거 연의 16회
4,9,다시 소패를 치는 여포군 앞에서 원군 하후돈이 조성의 화살에 한쪽 눈을 잃었다.,소패 구원 — 조성 · 엘리트 · 근거 연의 18회
4,10,함진영을 이끄는 고순이 소패 성문을 향해 총공격을 시작했다.,소패 — 고순 · 보스 · 근거 연의 18회 · 정사(함진영 = 『영웅기』)
4,11,진규·진등 부자의 계책에 속은 여포는 서주성을 비우고 소관으로 나섰다.,서주성 — 진등의 계책 · 일반 · 근거 연의 19회
4,12,계책이 번번이 무시당한 책사 진궁이 하비 외곽에 수비진을 쳤다.,하비 외곽 — 진궁 · 엘리트 · 근거 연의 19회
4,13,조조군이 기수와 사수의 둑을 터뜨리자 하비성이 물에 잠기기 시작했다.,하비 수공 · 일반 · 근거 연의 19회
4,14,후성·송헌·위속이 성문을 연 날 장료만은 끝까지 창을 놓지 않았다.,하비 성문 — 장료 · 엘리트 · 근거 연의 19회
4,15,모든 것을 잃은 여포가 백문루 앞에서 마지막 화극을 들었다.,하비 — 여포 · 보스 · 근거 연의 19회·각색(연의는 부하가 결박)
5,1,조조의 객장이 된 유비 일행은 허전 사냥 길목을 어지럽히는 도적을 쫓았다.,허도 근교 — 사냥터의 도적 · 일반 · 근거 연의 20회(배경)·가상
5,2,원술이 원소에게 가려 북상하자 유비는 차단을 자청해 허도를 떠났다.,허도 출진 — 원술 차단 · 일반 · 근거 연의 21회
5,3,옥새를 품고 원소에게 가는 원술 행렬의 선봉이 서주 남쪽에 나타났다.,서주 남쪽 — 원술군 선봉 · 일반 · 근거 연의 21회
5,4,황제를 칭한 원술의 화려한 친위대가 행렬을 지키고 있었다.,원술 친위대 · 일반 · 근거 가상
5,5,우이에서 관우와 비겼던 기령이 다시 길을 막자 장비가 앞으로 나섰다.,서주 남쪽 — 기령 · 보스 · 근거 연의 21회
5,6,꿀물 한 그릇을 찾다 숨진 원술의 잔병들이 수춘 북쪽 황무지로 흩어졌다.,원술의 몰락 — 패잔병 · 일반 · 근거 연의 21회
5,7,진등이 귀띔한 대로 서주성 앞에는 차주의 복병이 숨어 있었다.,서주성 앞 — 차주의 복병 · 일반 · 근거 연의 21회
5,8,조조의 밀명을 받은 차주가 서주성 성문을 걸어 잠갔다.,서주성 — 차주 · 엘리트 · 근거 연의 21회
5,9,서주를 되찾은 유비를 치려고 조조가 보낸 토벌군이 몰려왔다.,서주 외곽 — 조조 토벌군 · 일반 · 근거 연의 22회
5,10,조조의 장수 유대와 왕충이 진을 펼치고 유비 일행을 기다렸다.,서주 — 유대·왕충 · 보스(2인) · 근거 연의 22회
5,11,의대조가 드러나 조조가 친히 출병하자 장비는 소패에서 야습에 나섰다.,소패 야습 · 일반 · 근거 연의 24회
5,12,야습을 간파당한 형제들은 조조군에 쫓겨 뿔뿔이 흩어졌다.,소패 패주로 · 일반 · 근거 연의 24회
5,13,두 형수를 지키며 하비에 남은 관우 앞에 조조의 대군이 몰려왔다.,하비 — 고립된 관우 · 일반 · 근거 연의 25회
5,14,하후돈이 싸움을 걸고 달아나며 관우를 성 밖으로 꾀어냈다.,하비 성 밖 — 하후돈의 유인 · 엘리트 · 근거 연의 25회
5,15,하비로 돌아가는 길을 서황과 허저가 막아서자 관우는 토산에 고립되었다.,토산 — 서황·허저 · 보스(2인) · 근거 연의 25회·각색(결과)
6,1,조조의 진영에 몸을 맡긴 관우는 원소군에 포위된 백마로 향했다.,백마 포위망 · 일반 · 근거 연의 25회
6,2,안량의 칼에 송헌과 위속이 쓰러지고 서황마저 물러나 전선이 무너지고 있었다.,백마 — 쓰러진 송헌·위속 · 일반 · 근거 연의 25회
6,3,깃발 아래 앉은 안량의 본진까지 가는 길이 관우 앞에 열렸다.,백마 들판 — 안량 본진 앞 · 일반 · 근거 가상
6,4,관우의 단기 돌입을 막으려 원소군의 측면 기병이 몰려들었다.,백마 — 측면 기병 · 일반 · 근거 가상
6,5,하북의 명장 안량이 깃발 아래에서 다가오는 관우를 내려다보았다.,백마 — 안량 · 보스 · 근거 연의 25회
6,6,안량의 원수를 갚으려는 문추의 군이 황하를 건너 연진에 올랐다.,연진 — 원소군 도하 · 일반 · 근거 연의 26회
6,7,조조가 일부러 흘린 군량과 말에 문추의 군이 흩어져 있었다.,연진 — 버려진 군량과 말 · 일반 · 근거 연의 26회
6,8,장료와 서황이 문추에게 밀려난 자리에 관우가 말을 세웠다.,연진 — 장료·서황의 패퇴 · 일반 · 근거 연의 26회
6,9,강을 등진 문추의 친위대가 마지막 진을 쳤다.,연진 강변 — 문추 친위 · 일반 · 근거 가상
6,10,형제 같던 안량을 잃은 문추가 분노에 차 관우를 찾아 나섰다.,연진 — 문추 · 보스 · 근거 연의 26회
6,11,유비의 소식에 두 형수를 모시고 떠난 관우를 첫 관문 동령관의 공수가 막았다.,동령관 — 공수 · 엘리트 · 근거 연의 27회
6,12,낙양 태수 한복의 부장 맹탄이 싸우는 척 물러나며 관우를 끌어들였다.,낙양 외곽 — 맹탄 · 엘리트 · 근거 연의 27회
6,13,성문 뒤에 숨은 한복이 관우를 향해 활시위를 당겼다.,낙양 성문 — 한복 · 엘리트 · 근거 연의 27회
6,14,진국사의 스님 보정이 눈짓으로 절간에 숨은 칼잡이들을 알려 주었다.,사수관 — 진국사 매복 · 일반 · 근거 연의 27회
6,15,매복이 드러나자 변희가 유성추를 휘두르며 절 마당으로 뛰쳐나왔다.,사수관 — 변희 · 보스 · 근거 연의 27회
6,16,형양 태수 왕식이 친절한 얼굴로 객관을 내주었지만 밤은 고요하지 않았다.,형양 — 왕식의 연회 · 일반 · 근거 연의 27회
6,17,호반의 귀띔대로 객관에 불길이 치솟자 관우는 성문을 향해 길을 뚫었다.,형양 — 불붙은 객관 · 일반 · 근거 연의 27회
6,18,계략이 실패한 왕식이 군사를 이끌고 성문까지 관우를 쫓아왔다.,형양 성문 — 왕식 · 엘리트 · 근거 연의 27회
6,19,황하를 건널 배가 있는 활주 나루를 하후돈의 부장 진기가 막아섰다.,활주 나루 — 진기 · 엘리트 · 근거 연의 27회
6,20,다섯 관문을 지나 황하에 이른 관우를 하후돈이 끝까지 쫓아왔다.,황하 나루 — 하후돈 · 보스 · 근거 연의 28회·각색(연의는 승부 전 중단)
7,1,황하를 건넌 관우는 손건이 전한 소식을 따라 여남 쪽으로 길을 재촉했다.,황하 남쪽 — 순찰대 · 일반 · 근거 가상
7,2,관우를 흠모하던 주창이 따라나서자 남은 산적 무리가 칼을 들었다.,와우산 — 주창의 산채 · 일반 · 근거 연의 28회·가상(전투)
7,3,고성의 장비가 형님을 의심해 창을 겨누는 사이 채양의 선봉이 들이닥쳤다.,고성 — 의심하는 장비 · 일반 · 근거 연의 28회
7,4,생질 진기의 원수를 갚겠다는 채양의 본대가 고성 외곽을 메웠다.,고성 외곽 — 채양 본대 · 일반 · 근거 연의 28회
7,5,장비의 북이 세 번 울리기 전에 관우는 채양을 베어야 했다.,고성 — 채양 · 보스 · 근거 연의 28회
7,6,형주 유세를 핑계로 원소 진영을 빠져나온 유비를 원소군이 뒤쫓았다.,하북 경계 — 유비의 탈출 · 일반 · 근거 연의 28회·각색(추격전)
7,7,관정장에서 관평을 얻은 유비 일행 앞에 원소군 추격대가 들이닥쳤다.,관정장 — 관평 · 일반 · 근거 연의 28회·각색(전투)
7,8,와우산에서 배원소 무리를 쫓던 유비 일행은 그리던 조운과 다시 만났다.,와우산 — 배원소 · 엘리트 · 근거 연의 28회·각색(조운 단독 장면)
7,9,관도에서 원소를 꺾은 조조가 돌아와 양산의 유비군을 앞뒤로 조여 왔다.,양산 — 조조의 추격 · 엘리트 · 근거 연의 31회
7,10,유벽을 벤 고람이 산길을 막아서자 조운이 창을 고쳐 쥐었다.,양산 — 고람 · 보스 · 근거 연의 31회
8,1,양산에서 패한 유비 일행은 형주의 유표에게 몸을 맡기러 남쪽으로 향했다.,형주 가는 길 — 추격 잔당 · 일반 · 근거 가상
8,2,유표의 근심인 강하 반란을 진압하러 유비가 직접 군을 이끌었다.,강하 — 반란군 선봉 · 일반 · 근거 연의 34회(배경)·가상
8,3,산채 위에 자리 잡은 반란군 궁병이 쉴 새 없이 화살을 쏘아 댔다.,강하 산채 — 반란군 궁병 · 일반 · 근거 가상
8,4,빼앗긴 말을 되찾겠다며 진손이 유비 진영으로 달려들었다.,강하 — 진손 · 엘리트 · 근거 연의 34회·각색(순서)
8,5,명마 적로를 탄 반란군 대장 장무가 강변 들판에 나타났다.,강하 — 장무 · 보스 · 근거 연의 34회
8,6,이적의 귀띔에 술잔을 내려놓자 채모의 복병이 양양 연회장을 둘러싸고 있었다.,양양 연회 — 채모의 복병 · 엘리트 · 근거 연의 34회
8,7,채모의 추격대에 쫓긴 유비는 단계의 개울가에서 적로의 고삐를 당겼다.,단계 — 적로의 도약 · 일반 · 근거 연의 34회
8,8,조인이 보낸 여광이 신야로 쳐들어오자 군사 선복이 첫 계책을 내놓았다.,신야 — 여광 · 엘리트 · 근거 연의 35회
8,9,형 여광을 잃은 여상이 분노해 신야로 돌격해 왔다.,신야 — 여상 · 엘리트 · 근거 연의 35회
8,10,조인이 신야 앞에 펼친 팔문금쇄진을 선복이라 이름을 숨겼던 서서가 꿰뚫어 보았다.,신야 — 조인 · 팔문금쇄진 · 보스 · 근거 연의 36회
8,11,조인이 야습에 나선 사이 관우는 비어 있는 번성으로 향했다.,번성 — 빈 성 · 일반 · 근거 연의 36회
8,12,모친의 편지를 받은 서서가 떠나고 형제들은 반격해 온 조조군에게서 번성을 지켰다.,번성 방위 — 조조군 반격 · 일반 · 근거 가상
8,13,와룡을 찾아 세 번째로 융중에 오르는 눈길에 산적 무리가 숨어 있었다.,융중 가는 길 — 눈보라 속 산적 · 일반 · 근거 연의 37~38회(배경)·가상
8,14,제갈량의 지시대로 조운이 거짓으로 달아나며 하후돈의 선봉을 갈대숲 깊이 끌어들였다.,박망파 — 하후돈 선봉 · 일반 · 근거 연의 39회
8,15,하후돈의 10만 대군이 박망파 갈대밭에 들어서자 제갈량이 불화살을 명했다.,박망파 — 하후돈 · 보스 · 근거 연의 39회
9,1,백성을 모두 내보낸 신야에 조인과 조홍이 들어서자 성 곳곳에서 불길이 치솟았다.,신야 화공 — 조홍 · 엘리트 · 근거 연의 40회
9,2,관우는 모래 자루로 막아 둔 백하 상류의 둑을 터뜨릴 때를 기다렸다.,백하 — 관우의 수공 · 일반 · 근거 연의 40회
9,3,물에서 살아 나온 조인의 패잔병을 장비가 박릉 나루에서 기다렸다.,박릉 나루 — 장비 매복 · 일반 · 근거 연의 40회
9,4,유비를 따르는 10만 백성의 행렬이 한수를 건너기 시작했다.,번성 철수 — 백성 행렬 · 일반 · 근거 연의 41회
9,5,유종이 성문을 닫아 건 양양에서 위연이 문을 열려다 문빙과 맞붙었다.,양양 성문 — 문빙 · 보스 · 근거 연의 41회·각색
9,6,백성과 함께 더디게 남하하던 유비군을 조조의 호표기가 밤낮없이 쫓아왔다.,당양 — 호표기의 추격 · 일반 · 근거 연의 41회·정사(조순의 호표기)
9,7,흩어진 가족을 찾아 적진으로 돌아간 조운 앞에 미축을 묶어 가던 순우도가 나타났다.,장판 — 순우도 · 엘리트 · 근거 연의 41회
9,8,조조의 보검 청강검을 찬 하후은이 조운의 앞을 가로막았다.,장판 — 하후은 · 엘리트 · 근거 연의 41회
9,9,아두를 품에 안은 조운을 안명과 하북의 네 장수가 겹겹이 막아섰다.,장판 — 안명과 하북 4장 · 엘리트 · 근거 연의 41회·각색(순서)
9,10,아두를 품은 조운이 구덩이에 빠지자 장합이 창을 들고 달려들었다.,장판파 — 장합 · 보스 · 근거 연의 41회
9,11,장판교 위에 홀로 선 장비 앞에서 조조의 대군이 걸음을 멈췄다.,장판교 — 장비의 일갈 · 엘리트 · 근거 연의 42회
9,12,장판교를 끊은 것이 들키자 조조의 대군이 다시 쫓아오기 시작했다.,부서진 장판교 · 일반 · 근거 연의 42회
9,13,유비 일행은 한수의 나루 한진을 향해 마지막 달음질을 했다.,한진 가는 길 — 조조 철기 · 일반 · 근거 가상
9,14,강하에서 온 관우와 유기의 배에 오를 때까지 나루를 지켜야 했다.,한진 — 관우·유기의 수군 · 일반 · 근거 연의 42회·각색
9,15,나루 언덕까지 쫓아온 조조가 직접 군을 이끌고 모습을 드러냈다.,한진 나루 — 조조 · 보스 · 근거 연의 42회·각색(연의는 원군을 보고 물러남)
10,1,강하에 모인 유비군을 엿보려 조조군 정찰 선단이 하구로 다가왔다.,하구 — 조조군 정찰선 · 일반 · 근거 가상
10,2,손권과 동맹을 맺으러 가는 뱃길에 형주 수군의 경계선이 놓여 있었다.,장강 — 형주 수군 경계선 · 일반 · 근거 가상
10,3,주유의 수군이 삼강구로 나아가자 형주 수군 장수 채훈의 배가 앞을 막았다.,삼강구 — 채훈 · 엘리트 · 근거 연의 45회
10,4,물에 서툰 북방 병사와 형주 수군이 뒤섞인 선단이 삼강구를 메웠다.,삼강구 — 형주 수군 본대 · 일반 · 근거 연의 45회
10,5,형주 수군 도독 채모와 장윤이 기함 위에서 수군을 지휘하고 있었다.,삼강구 — 채모·장윤 · 보스(2인) · 근거 연의 45회
10,6,짙은 안개 속 짚단을 실은 배들이 조조의 수채를 향해 북을 울렸다.,초선차전 — 안개 속 화살비 · 일반 · 근거 연의 46회
10,7,고육계로 피투성이가 된 황개의 밀서를 품고 감택이 북안에 올랐다.,장강 북안 — 감택의 밀서 · 일반 · 근거 연의 46~47회(배경)·가상
10,8,방통의 권유로 사슬에 묶인 조조의 함대가 흔들림 없이 장강을 덮었다.,연환선 — 사슬로 묶인 함대 · 일반 · 근거 연의 47회(배경)·가상
10,9,동남풍을 기다리는 밤 오림 수채 앞을 조조군 순찰 선단이 오갔다.,오림 수채 앞 — 순찰 선단 · 일반 · 근거 가상
10,10,채모를 대신해 수군을 맡은 우금과 모개가 연환선단을 이끌고 나왔다.,연환선단 — 우금·모개 · 보스(2인) · 근거 연의 45회(배경)·각색
10,11,칠성단에 동남풍이 불자 황개의 화선이 조조의 수채를 향해 돛을 올렸다.,동남풍 — 화선 출격 · 일반 · 근거 연의 49회
10,12,사슬에 묶여 달아나지 못하는 조조의 함대가 붉은 불길에 휩싸였다.,적벽 — 불타는 연환선 · 일반 · 근거 연의 49회
10,13,거짓 투항한 채중을 앞세운 감녕이 수채 안 깊숙이 불을 질렀다.,수채 — 감녕과 채중 · 엘리트 · 근거 연의 49~50회
10,14,조조를 태울 작은 배를 지키려 친위대가 불길 속에 버티고 있었다.,수채 본진 — 불길 속 친위대 · 일반 · 근거 가상
10,15,황개를 화살로 떨어뜨린 장료가 조조를 태우고 북안으로 달아나려 했다.,적벽 — 장료 · 보스 · 근거 연의 49회
10,16,불타는 적벽을 뒤로하고 달아나는 조조 앞에 오림의 숲길에서 조운이 뛰쳐나왔다.,오림 — 조운의 매복 · 엘리트 · 근거 연의 50회
10,17,호로구에서 밥을 짓던 조조의 패잔병 앞에 장비가 나타났다.,호로구 — 장비의 매복 · 엘리트 · 근거 연의 50회
10,18,비에 젖은 화용도의 진흙길에 조조의 패잔병이 발이 묶였다.,화용도 — 진흙길 · 일반 · 근거 연의 50회
10,19,3백여 기만 남은 조조의 친위대가 화용도를 필사적으로 지켰다.,화용도 — 마지막 호위대 · 일반 · 근거 가상
10,20,화용도 길목을 지키던 관우 앞에 지친 조조가 모습을 드러냈다.,화용도 — 조조 · 보스 · 근거 연의 50회·각색(연의는 싸우지 않고 놓아줌)
1 n_chapter n_stage s_desc_ko Memo
2 1 1 의용군 방이 붙은 탁현 저잣거리에서 장비가 황건 앞잡이 건달들에게 둘러싸였다. 탁현 저잣거리 — 장비 구출 · 튜토리얼(조작) · 근거 연의 1회 각색(방 앞 만남 → 장비 구출)
3 1 2 탁현 외곽 고갯길에서 떠돌던 무사 관우가 황건 척후들에게 포위되었다. 탁현 고갯길 — 관우 구출 · 튜토리얼(아군 밀치기 · 3턴) · 근거 연의 1회 각색(주막 만남 → 관우 구출)
4 1 3 셋이 함께 누상촌으로 돌아가던 길에 황건 무리가 사방에서 몰려왔다. 누상촌 어귀 — 포위 돌파 · 튜토리얼(장수 스킬) · 근거 연의 1회 각색 · 클리어 뒤 도원결의
5 1 4 도원에서 의형제를 맺은 세 사람이 대흥산에 닿자 정원지의 부장 등무가 앞을 막았다. 대흥산 — 등무 · 엘리트 · 튜토리얼(상성) · 근거 연의 1회
6 1 5 부장을 잃고 분노한 정원지가 황건 5만을 이끌고 산기슭으로 몰려왔다. 대흥산 전투 — 정원지 · 보스 · 튜토리얼(보스·바위) · 근거 연의 1회
7 1 6 청주태수 공경의 구원 요청에 달려가니 성은 황건 포위망에 갇혀 있었다. 청주 포위망 · 일반 · 튜토리얼(보병 연쇄·목책) · 근거 연의 1회
8 1 7 유비가 미끼가 되어 물러나는 사이 관우와 장비는 산 뒤에 숨어 적을 기다렸다. 청주 산골 매복 · 일반 · 튜토리얼(기병 관통·함정) · 근거 연의 1회
9 1 8 스승 노식의 명으로 영천에 이르니 관군의 화공에 쫓긴 황건이 불길 속을 달아나고 있었다. 영천 — 불길 속 황건 · 엘리트 · 튜토리얼(창병 밀치기·불길) · 근거 연의 1회·각색(유비군 도착 전 승부가 남 · 장보의 요술은 2회 곡양 장면을 가져옴)
10 1 9 모함으로 압송되는 스승 노식을 뒤로하고 광종에 이르자 장량의 황건 전위가 길을 막았다. 광종 — 황건 본진 전위 · 엘리트 · 튜토리얼(궁병 사선·자유 편성) · 근거 연의 1회·각색(장량 배치)
11 1 10 패주하는 동탁을 구하려 세 형제는 천공장군 장각의 대군 한가운데로 뛰어들었다. 광종 결전 — 장각 · 보스 · 종합 · 근거 연의 1회·각색(연의 2회는 관군 도착 전 장각이 이미 죽은 것으로만 나옴 · 병사 = 정사 — 결말 텍스트)
12 2 1 18로 제후가 모인 산조 진영 주변에 동탁군 척후 기병이 어른거렸다. 산조 진영 — 동탁군 척후 · 일반 · 근거 가상
13 2 2 공손찬 군의 말석에 선 유비 일행은 사수관으로 향하는 산길에 올랐다. 사수관 가는 길 · 일반 · 근거 가상
14 2 3 손견의 선봉이 사수관에 닿자 동탁군 장수 호진이 관문 앞에 진을 쳤다. 사수관 앞 — 호진 · 엘리트 · 근거 연의 5회·각색(연의는 정보가 호진을 벰 → 결말 텍스트)
15 2 4 군량이 끊긴 손견의 진영에 화웅의 야습이 덮쳐 와 밤하늘이 불타올랐다. 손견 진영 야습 · 일반 · 근거 연의 5회·각색
16 2 5 연합의 장수들이 잇달아 쓰러지자 마궁수 관우가 데운 술을 두고 관문 앞으로 나섰다. 사수관 — 화웅 · 보스 · 근거 연의 5회
17 2 6 화웅을 잃은 사수관 수비대가 관문 안쪽에서 무너지기 시작했다. 사수관 함락 — 잔병 · 일반 · 근거 가상
18 2 7 동탁이 친히 호로관으로 나서자 서량 기병대가 연합의 앞을 막아섰다. 호로관 가는 길 — 서량 기병 · 일반 · 근거 가상
19 2 8 방열과 목순이 여포에게 단번에 쓰러진 호로관 앞에 다시 적이 몰려들었다. 호로관 앞 — 방열이 쓰러진 자리 · 일반 · 근거 연의 5회(배경) · 가상(전투)
20 2 9 공손찬마저 쫓기게 만든 여포의 철기를 끊으려 유비 일행은 관문 측면으로 돌았다. 호로관 측면 — 적토마 돌격대 · 일반 · 근거 연의 5회·각색
21 2 10 천하무쌍 여포가 적토마를 몰고 나오자 장비가 먼저 장팔사모를 겨눴다. 호로관 — 여포 · 보스 · 근거 연의 5회
22 3 1 공손찬의 원군 요청을 받은 유비 일행은 평원을 떠나 반하로 향했다. 평원 출진 — 원소군 척후 · 일반 · 근거 가상
23 3 2 반하에 이르자 원소군의 경계 기병과 보병이 강변 들판을 지키고 있었다. 반하 들판 · 일반 · 근거 가상
24 3 3 쫓기는 공손찬 앞에 백마를 탄 젊은 장수 조운이 나타나 문추를 막아섰다. 반하 다리 — 문추의 추격 · 엘리트 · 근거 연의 7회·각색(조운 단독 장면에 유비군 동참)
25 3 4 공손찬의 장수 엄강을 쓰러뜨린 원소군 노병이 강변에 화살비를 퍼부었다. 반하 — 엄강의 패전 · 일반 · 근거 연의 7회
26 3 5 선등 노병을 이끄는 국의가 직접 활을 들고 강변 진영에 버티고 섰다. 반하 — 국의 · 보스 · 근거 연의 7회
27 3 6 북해의 공융이 위태롭다는 소식에 길을 나서자 청주를 휩쓰는 황건 잔당이 앞을 막았다. 북해 가는 길 — 황건 잔당 · 일반 · 근거 가상
28 3 7 관해의 수만 대군이 공융의 북해성을 겹겹이 에워싸고 있었다. 북해 포위망 바깥 · 일반 · 근거 연의 11회
29 3 8 포위를 뚫고 나온 태사자와 함께 유비 일행은 성으로 가는 길을 열었다. 태사자의 돌파로 · 일반 · 근거 연의 11회
30 3 9 성문을 두드리는 관해의 친위 무리를 몰아내야 북해를 구할 수 있었다. 북해 성문 — 관해 친위 · 일반 · 근거 가상
31 3 10 황건 잔당의 거한 관해가 큰 칼을 들고 성문 앞에 버티고 섰다. 북해 — 관해 · 보스 · 근거 연의 11회
32 3 11 부친의 원수를 갚겠다는 조조군이 서주의 마을들을 불태우고 있었다. 서주 가는 길 — 불타는 마을 · 일반 · 근거 연의 10회(배경)·가상
33 3 12 공손찬에게 빌린 조운과 함께 유비 일행은 서주를 둘러싼 조조의 포위진에 닿았다. 서주 외곽 — 조조 포위진 · 일반 · 근거 연의 11회
34 3 13 조조군 약탈대에 쫓기는 피난민 행렬이 서주 남쪽 들판을 메우고 있었다. 서주 남쪽 — 피난민 행렬 · 일반 · 근거 가상
35 3 14 유비와 장비는 1천 군사로 조조 진영의 가장자리를 뚫고 들어갔다. 조조 진영 외곽 · 일반 · 근거 연의 11회
36 3 15 조조 진영을 돌파하려는 유비 일행 앞에 조조의 장수 우금이 막아섰다. 서주 — 우금 · 보스 · 근거 연의 11회
37 4 1 서주를 노리는 원술의 대군을 막으려 유비 일행은 회수 가의 우이로 나아갔다. 우이 들판 — 원술군 선봉 · 일반 · 근거 연의 14회(배경)·가상
38 4 2 원술군의 군량선이 회음 강변을 따라 올라오고 있었다. 회음 강변 — 군량 수송대 · 일반 · 근거 가상
39 4 3 기령의 부장 순정이 관우를 노리고 진 앞으로 뛰쳐나왔다. 우이 — 순정 · 엘리트 · 근거 연의 14회
40 4 4 유비 일행은 밤을 틈타 기령의 진영을 덮치기로 했다. 우이 진영 야습 · 일반 · 근거 가상
41 4 5 원술군 대장 기령이 삼첨도를 들고 관우와 맞서러 나왔다. 우이 — 기령 · 보스 · 근거 연의 14회
42 4 6 장비에게 매를 맞은 조표가 성문을 열자 여포의 기병이 서주성으로 들이쳤다. 서주성의 밤 — 조표의 배신 · 일반 · 근거 연의 14회(정사는 하비)
43 4 7 장비가 여포의 말을 빼앗은 일로 화가 난 여포가 소패로 군을 몰아왔다. 소패 — 빼앗긴 말 · 일반 · 근거 연의 16회
44 4 8 소패를 잃은 유비 일행은 허도의 조조에게 몸을 맡기려 서쪽으로 달렸다. 소패 탈출 — 여포군 추격 · 일반 · 근거 연의 16회
45 4 9 다시 소패를 치는 여포군 앞에서 원군 하후돈이 조성의 화살에 한쪽 눈을 잃었다. 소패 구원 — 조성 · 엘리트 · 근거 연의 18회
46 4 10 함진영을 이끄는 고순이 소패 성문을 향해 총공격을 시작했다. 소패 — 고순 · 보스 · 근거 연의 18회 · 정사(함진영 = 『영웅기』)
47 4 11 진규·진등 부자의 계책에 속은 여포는 서주성을 비우고 소관으로 나섰다. 서주성 — 진등의 계책 · 일반 · 근거 연의 19회
48 4 12 계책이 번번이 무시당한 책사 진궁이 하비 외곽에 수비진을 쳤다. 하비 외곽 — 진궁 · 엘리트 · 근거 연의 19회
49 4 13 조조군이 기수와 사수의 둑을 터뜨리자 하비성이 물에 잠기기 시작했다. 하비 수공 · 일반 · 근거 연의 19회
50 4 14 후성·송헌·위속이 성문을 연 날 장료만은 끝까지 창을 놓지 않았다. 하비 성문 — 장료 · 엘리트 · 근거 연의 19회
51 4 15 모든 것을 잃은 여포가 백문루 앞에서 마지막 화극을 들었다. 하비 — 여포 · 보스 · 근거 연의 19회·각색(연의는 부하가 결박)
52 5 1 조조의 객장이 된 유비 일행은 허전 사냥 길목을 어지럽히는 도적을 쫓았다. 허도 근교 — 사냥터의 도적 · 일반 · 근거 연의 20회(배경)·가상
53 5 2 원술이 원소에게 가려 북상하자 유비는 차단을 자청해 허도를 떠났다. 허도 출진 — 원술 차단 · 일반 · 근거 연의 21회
54 5 3 옥새를 품고 원소에게 가는 원술 행렬의 선봉이 서주 남쪽에 나타났다. 서주 남쪽 — 원술군 선봉 · 일반 · 근거 연의 21회
55 5 4 황제를 칭한 원술의 화려한 친위대가 행렬을 지키고 있었다. 원술 친위대 · 일반 · 근거 가상
56 5 5 우이에서 관우와 비겼던 기령이 다시 길을 막자 장비가 앞으로 나섰다. 서주 남쪽 — 기령 · 보스 · 근거 연의 21회
57 5 6 꿀물 한 그릇을 찾다 숨진 원술의 잔병들이 수춘 북쪽 황무지로 흩어졌다. 원술의 몰락 — 패잔병 · 일반 · 근거 연의 21회
58 5 7 진등이 귀띔한 대로 서주성 앞에는 차주의 복병이 숨어 있었다. 서주성 앞 — 차주의 복병 · 일반 · 근거 연의 21회
59 5 8 조조의 밀명을 받은 차주가 서주성 성문을 걸어 잠갔다. 서주성 — 차주 · 엘리트 · 근거 연의 21회
60 5 9 서주를 되찾은 유비를 치려고 조조가 보낸 토벌군이 몰려왔다. 서주 외곽 — 조조 토벌군 · 일반 · 근거 연의 22회
61 5 10 조조의 장수 유대와 왕충이 진을 펼치고 유비 일행을 기다렸다. 서주 — 유대·왕충 · 보스(2인) · 근거 연의 22회
62 5 11 의대조가 드러나 조조가 친히 출병하자 장비는 소패에서 야습에 나섰다. 소패 야습 · 일반 · 근거 연의 24회
63 5 12 야습을 간파당한 형제들은 조조군에 쫓겨 뿔뿔이 흩어졌다. 소패 패주로 · 일반 · 근거 연의 24회
64 5 13 두 형수를 지키며 하비에 남은 관우 앞에 조조의 대군이 몰려왔다. 하비 — 고립된 관우 · 일반 · 근거 연의 25회
65 5 14 하후돈이 싸움을 걸고 달아나며 관우를 성 밖으로 꾀어냈다. 하비 성 밖 — 하후돈의 유인 · 엘리트 · 근거 연의 25회
66 5 15 하비로 돌아가는 길을 서황과 허저가 막아서자 관우는 토산에 고립되었다. 토산 — 서황·허저 · 보스(2인) · 근거 연의 25회·각색(결과)
67 6 1 조조의 진영에 몸을 맡긴 관우는 원소군에 포위된 백마로 향했다. 백마 포위망 · 일반 · 근거 연의 25회
68 6 2 안량의 칼에 송헌과 위속이 쓰러지고 서황마저 물러나 전선이 무너지고 있었다. 백마 — 쓰러진 송헌·위속 · 일반 · 근거 연의 25회
69 6 3 깃발 아래 앉은 안량의 본진까지 가는 길이 관우 앞에 열렸다. 백마 들판 — 안량 본진 앞 · 일반 · 근거 가상
70 6 4 관우의 단기 돌입을 막으려 원소군의 측면 기병이 몰려들었다. 백마 — 측면 기병 · 일반 · 근거 가상
71 6 5 하북의 명장 안량이 깃발 아래에서 다가오는 관우를 내려다보았다. 백마 — 안량 · 보스 · 근거 연의 25회
72 6 6 안량의 원수를 갚으려는 문추의 군이 황하를 건너 연진에 올랐다. 연진 — 원소군 도하 · 일반 · 근거 연의 26회
73 6 7 조조가 일부러 흘린 군량과 말에 문추의 군이 흩어져 있었다. 연진 — 버려진 군량과 말 · 일반 · 근거 연의 26회
74 6 8 장료와 서황이 문추에게 밀려난 자리에 관우가 말을 세웠다. 연진 — 장료·서황의 패퇴 · 일반 · 근거 연의 26회
75 6 9 강을 등진 문추의 친위대가 마지막 진을 쳤다. 연진 강변 — 문추 친위 · 일반 · 근거 가상
76 6 10 형제 같던 안량을 잃은 문추가 분노에 차 관우를 찾아 나섰다. 연진 — 문추 · 보스 · 근거 연의 26회
77 6 11 유비의 소식에 두 형수를 모시고 떠난 관우를 첫 관문 동령관의 공수가 막았다. 동령관 — 공수 · 엘리트 · 근거 연의 27회
78 6 12 낙양 태수 한복의 부장 맹탄이 싸우는 척 물러나며 관우를 끌어들였다. 낙양 외곽 — 맹탄 · 엘리트 · 근거 연의 27회
79 6 13 성문 뒤에 숨은 한복이 관우를 향해 활시위를 당겼다. 낙양 성문 — 한복 · 엘리트 · 근거 연의 27회
80 6 14 진국사의 스님 보정이 눈짓으로 절간에 숨은 칼잡이들을 알려 주었다. 사수관 — 진국사 매복 · 일반 · 근거 연의 27회
81 6 15 매복이 드러나자 변희가 유성추를 휘두르며 절 마당으로 뛰쳐나왔다. 사수관 — 변희 · 보스 · 근거 연의 27회
82 6 16 형양 태수 왕식이 친절한 얼굴로 객관을 내주었지만 밤은 고요하지 않았다. 형양 — 왕식의 연회 · 일반 · 근거 연의 27회
83 6 17 호반의 귀띔대로 객관에 불길이 치솟자 관우는 성문을 향해 길을 뚫었다. 형양 — 불붙은 객관 · 일반 · 근거 연의 27회
84 6 18 계략이 실패한 왕식이 군사를 이끌고 성문까지 관우를 쫓아왔다. 형양 성문 — 왕식 · 엘리트 · 근거 연의 27회
85 6 19 황하를 건널 배가 있는 활주 나루를 하후돈의 부장 진기가 막아섰다. 활주 나루 — 진기 · 엘리트 · 근거 연의 27회
86 6 20 다섯 관문을 지나 황하에 이른 관우를 하후돈이 끝까지 쫓아왔다. 황하 나루 — 하후돈 · 보스 · 근거 연의 28회·각색(연의는 승부 전 중단)
87 7 1 황하를 건넌 관우는 손건이 전한 소식을 따라 여남 쪽으로 길을 재촉했다. 황하 남쪽 — 순찰대 · 일반 · 근거 가상
88 7 2 관우를 흠모하던 주창이 따라나서자 남은 산적 무리가 칼을 들었다. 와우산 — 주창의 산채 · 일반 · 근거 연의 28회·가상(전투)
89 7 3 고성의 장비가 형님을 의심해 창을 겨누는 사이 채양의 선봉이 들이닥쳤다. 고성 — 의심하는 장비 · 일반 · 근거 연의 28회
90 7 4 생질 진기의 원수를 갚겠다는 채양의 본대가 고성 외곽을 메웠다. 고성 외곽 — 채양 본대 · 일반 · 근거 연의 28회
91 7 5 장비의 북이 세 번 울리기 전에 관우는 채양을 베어야 했다. 고성 — 채양 · 보스 · 근거 연의 28회
92 7 6 형주 유세를 핑계로 원소 진영을 빠져나온 유비를 원소군이 뒤쫓았다. 하북 경계 — 유비의 탈출 · 일반 · 근거 연의 28회·각색(추격전)
93 7 7 관정장에서 관평을 얻은 유비 일행 앞에 원소군 추격대가 들이닥쳤다. 관정장 — 관평 · 일반 · 근거 연의 28회·각색(전투)
94 7 8 와우산에서 배원소 무리를 쫓던 유비 일행은 그리던 조운과 다시 만났다. 와우산 — 배원소 · 엘리트 · 근거 연의 28회·각색(조운 단독 장면)
95 7 9 관도에서 원소를 꺾은 조조가 돌아와 양산의 유비군을 앞뒤로 조여 왔다. 양산 — 조조의 추격 · 엘리트 · 근거 연의 31회
96 7 10 유벽을 벤 고람이 산길을 막아서자 조운이 창을 고쳐 쥐었다. 양산 — 고람 · 보스 · 근거 연의 31회
97 8 1 양산에서 패한 유비 일행은 형주의 유표에게 몸을 맡기러 남쪽으로 향했다. 형주 가는 길 — 추격 잔당 · 일반 · 근거 가상
98 8 2 유표의 근심인 강하 반란을 진압하러 유비가 직접 군을 이끌었다. 강하 — 반란군 선봉 · 일반 · 근거 연의 34회(배경)·가상
99 8 3 산채 위에 자리 잡은 반란군 궁병이 쉴 새 없이 화살을 쏘아 댔다. 강하 산채 — 반란군 궁병 · 일반 · 근거 가상
100 8 4 빼앗긴 말을 되찾겠다며 진손이 유비 진영으로 달려들었다. 강하 — 진손 · 엘리트 · 근거 연의 34회·각색(순서)
101 8 5 명마 적로를 탄 반란군 대장 장무가 강변 들판에 나타났다. 강하 — 장무 · 보스 · 근거 연의 34회
102 8 6 이적의 귀띔에 술잔을 내려놓자 채모의 복병이 양양 연회장을 둘러싸고 있었다. 양양 연회 — 채모의 복병 · 엘리트 · 근거 연의 34회
103 8 7 채모의 추격대에 쫓긴 유비는 단계의 개울가에서 적로의 고삐를 당겼다. 단계 — 적로의 도약 · 일반 · 근거 연의 34회
104 8 8 조인이 보낸 여광이 신야로 쳐들어오자 군사 선복이 첫 계책을 내놓았다. 신야 — 여광 · 엘리트 · 근거 연의 35회
105 8 9 형 여광을 잃은 여상이 분노해 신야로 돌격해 왔다. 신야 — 여상 · 엘리트 · 근거 연의 35회
106 8 10 조인이 신야 앞에 펼친 팔문금쇄진을 선복이라 이름을 숨겼던 서서가 꿰뚫어 보았다. 신야 — 조인 · 팔문금쇄진 · 보스 · 근거 연의 36회
107 8 11 조인이 야습에 나선 사이 관우는 비어 있는 번성으로 향했다. 번성 — 빈 성 · 일반 · 근거 연의 36회
108 8 12 모친의 편지를 받은 서서가 떠나고 형제들은 반격해 온 조조군에게서 번성을 지켰다. 번성 방위 — 조조군 반격 · 일반 · 근거 가상
109 8 13 와룡을 찾아 세 번째로 융중에 오르는 눈길에 산적 무리가 숨어 있었다. 융중 가는 길 — 눈보라 속 산적 · 일반 · 근거 연의 37~38회(배경)·가상
110 8 14 제갈량의 지시대로 조운이 거짓으로 달아나며 하후돈의 선봉을 갈대숲 깊이 끌어들였다. 박망파 — 하후돈 선봉 · 일반 · 근거 연의 39회
111 8 15 하후돈의 10만 대군이 박망파 갈대밭에 들어서자 제갈량이 불화살을 명했다. 박망파 — 하후돈 · 보스 · 근거 연의 39회
112 9 1 백성을 모두 내보낸 신야에 조인과 조홍이 들어서자 성 곳곳에서 불길이 치솟았다. 신야 화공 — 조홍 · 엘리트 · 근거 연의 40회
113 9 2 관우는 모래 자루로 막아 둔 백하 상류의 둑을 터뜨릴 때를 기다렸다. 백하 — 관우의 수공 · 일반 · 근거 연의 40회
114 9 3 물에서 살아 나온 조인의 패잔병을 장비가 박릉 나루에서 기다렸다. 박릉 나루 — 장비 매복 · 일반 · 근거 연의 40회
115 9 4 유비를 따르는 10만 백성의 행렬이 한수를 건너기 시작했다. 번성 철수 — 백성 행렬 · 일반 · 근거 연의 41회
116 9 5 유종이 성문을 닫아 건 양양에서 위연이 문을 열려다 문빙과 맞붙었다. 양양 성문 — 문빙 · 보스 · 근거 연의 41회·각색
117 9 6 백성과 함께 더디게 남하하던 유비군을 조조의 호표기가 밤낮없이 쫓아왔다. 당양 — 호표기의 추격 · 일반 · 근거 연의 41회·정사(조순의 호표기)
118 9 7 흩어진 가족을 찾아 적진으로 돌아간 조운 앞에 미축을 묶어 가던 순우도가 나타났다. 장판 — 순우도 · 엘리트 · 근거 연의 41회
119 9 8 조조의 보검 청강검을 찬 하후은이 조운의 앞을 가로막았다. 장판 — 하후은 · 엘리트 · 근거 연의 41회
120 9 9 아두를 품에 안은 조운을 안명과 하북의 네 장수가 겹겹이 막아섰다. 장판 — 안명과 하북 4장 · 엘리트 · 근거 연의 41회·각색(순서)
121 9 10 아두를 품은 조운이 구덩이에 빠지자 장합이 창을 들고 달려들었다. 장판파 — 장합 · 보스 · 근거 연의 41회
122 9 11 장판교 위에 홀로 선 장비 앞에서 조조의 대군이 걸음을 멈췄다. 장판교 — 장비의 일갈 · 엘리트 · 근거 연의 42회
123 9 12 장판교를 끊은 것이 들키자 조조의 대군이 다시 쫓아오기 시작했다. 부서진 장판교 · 일반 · 근거 연의 42회
124 9 13 유비 일행은 한수의 나루 한진을 향해 마지막 달음질을 했다. 한진 가는 길 — 조조 철기 · 일반 · 근거 가상
125 9 14 강하에서 온 관우와 유기의 배에 오를 때까지 나루를 지켜야 했다. 한진 — 관우·유기의 수군 · 일반 · 근거 연의 42회·각색
126 9 15 나루 언덕까지 쫓아온 조조가 직접 군을 이끌고 모습을 드러냈다. 한진 나루 — 조조 · 보스 · 근거 연의 42회·각색(연의는 원군을 보고 물러남)
127 10 1 강하에 모인 유비군을 엿보려 조조군 정찰 선단이 하구로 다가왔다. 하구 — 조조군 정찰선 · 일반 · 근거 가상
128 10 2 손권과 동맹을 맺으러 가는 뱃길에 형주 수군의 경계선이 놓여 있었다. 장강 — 형주 수군 경계선 · 일반 · 근거 가상
129 10 3 주유의 수군이 삼강구로 나아가자 형주 수군 장수 채훈의 배가 앞을 막았다. 삼강구 — 채훈 · 엘리트 · 근거 연의 45회
130 10 4 물에 서툰 북방 병사와 형주 수군이 뒤섞인 선단이 삼강구를 메웠다. 삼강구 — 형주 수군 본대 · 일반 · 근거 연의 45회
131 10 5 형주 수군 도독 채모와 장윤이 기함 위에서 수군을 지휘하고 있었다. 삼강구 — 채모·장윤 · 보스(2인) · 근거 연의 45회
132 10 6 짙은 안개 속 짚단을 실은 배들이 조조의 수채를 향해 북을 울렸다. 초선차전 — 안개 속 화살비 · 일반 · 근거 연의 46회
133 10 7 고육계로 피투성이가 된 황개의 밀서를 품고 감택이 북안에 올랐다. 장강 북안 — 감택의 밀서 · 일반 · 근거 연의 46~47회(배경)·가상
134 10 8 방통의 권유로 사슬에 묶인 조조의 함대가 흔들림 없이 장강을 덮었다. 연환선 — 사슬로 묶인 함대 · 일반 · 근거 연의 47회(배경)·가상
135 10 9 동남풍을 기다리는 밤 오림 수채 앞을 조조군 순찰 선단이 오갔다. 오림 수채 앞 — 순찰 선단 · 일반 · 근거 가상
136 10 10 채모를 대신해 수군을 맡은 우금과 모개가 연환선단을 이끌고 나왔다. 연환선단 — 우금·모개 · 보스(2인) · 근거 연의 45회(배경)·각색
137 10 11 칠성단에 동남풍이 불자 황개의 화선이 조조의 수채를 향해 돛을 올렸다. 동남풍 — 화선 출격 · 일반 · 근거 연의 49회
138 10 12 사슬에 묶여 달아나지 못하는 조조의 함대가 붉은 불길에 휩싸였다. 적벽 — 불타는 연환선 · 일반 · 근거 연의 49회
139 10 13 거짓 투항한 채중을 앞세운 감녕이 수채 안 깊숙이 불을 질렀다. 수채 — 감녕과 채중 · 엘리트 · 근거 연의 49~50회
140 10 14 조조를 태울 작은 배를 지키려 친위대가 불길 속에 버티고 있었다. 수채 본진 — 불길 속 친위대 · 일반 · 근거 가상
141 10 15 황개를 화살로 떨어뜨린 장료가 조조를 태우고 북안으로 달아나려 했다. 적벽 — 장료 · 보스 · 근거 연의 49회
142 10 16 불타는 적벽을 뒤로하고 달아나는 조조 앞에 오림의 숲길에서 조운이 뛰쳐나왔다. 오림 — 조운의 매복 · 엘리트 · 근거 연의 50회
143 10 17 호로구에서 밥을 짓던 조조의 패잔병 앞에 장비가 나타났다. 호로구 — 장비의 매복 · 엘리트 · 근거 연의 50회
144 10 18 비에 젖은 화용도의 진흙길에 조조의 패잔병이 발이 묶였다. 화용도 — 진흙길 · 일반 · 근거 연의 50회
145 10 19 3백여 기만 남은 조조의 친위대가 화용도를 필사적으로 지켰다. 화용도 — 마지막 호위대 · 일반 · 근거 가상
146 10 20 화용도 길목을 지키던 관우 앞에 지친 조조가 모습을 드러냈다. 화용도 — 조조 · 보스 · 근거 연의 50회·각색(연의는 싸우지 않고 놓아줌)

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 81d5f8b013b89eb448418254d45e4e12
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,181 @@
fileFormatVersion: 2
guid: 719eef0753f14c288ed26f1ff3c58fbd
TextureImporter:
internalIDToNameTable:
- first:
213: -166343660977832731
second: f000_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 0
alignment: 9
spritePivot: {x: 0.50000, y: 0.50000}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: iOS
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: f000_0
rect:
serializedVersion: 2
x: 19
y: 19
width: 898
height: 820
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: 77d9d37c867d4c55926fb7bb69c19fbc
internalID: -166343660977832731
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 81270df211b64dfbb081b1b0e483f8ce
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,41 @@
using System.IO;
using TKS.OutGame;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
namespace TKS.EditorTools
{
/// <summary>
/// 시나리오 이벤트(전장 설명 · 보스 등장 연출) 검증 캡처 — 2026-11-12 개발 요청서 C1·C2.
/// Unity.exe -projectPath &lt;proj&gt; -force-d3d11 -executeMethod TKS.EditorTools.ScenarioCapture.Run -scDir &lt;dir&gt;
/// [-scPopups 1-1,1-10] [-scStages 1-10,5-10,10-20] [-scTimes 0.3,1.0,1.6,2.4,3.4,4.8]
/// 팝업 = 그 스테이지 팝업 1장 · 스테이지 = 보스 연출을 시각마다 1장 + 아군 차례 1장 · 끝나면 스스로 종료.
/// </summary>
public static class ScenarioCapture
{
public static void Run()
{
string dir = Arg("-scDir");
if (string.IsNullOrEmpty(dir)) dir = Path.Combine(Directory.GetCurrentDirectory(), "Logs", "scenario_capture");
DataImporter.ImportAll();
UIThemeImporter.Import();
EditorSceneManager.OpenScene(ProjectSetup.ScenePath, OpenSceneMode.Single);
SessionState.SetBool(SaveStore.MemoryFlagKey, true);
SessionState.SetString(ScenarioCaptureDriver.DirKey, dir);
SessionState.SetString(ScenarioCaptureDriver.PopupKey, Arg("-scPopups") ?? "1-1,1-10");
SessionState.SetString(ScenarioCaptureDriver.StagesKey, Arg("-scStages") ?? "1-10,5-10,10-20");
SessionState.SetString(ScenarioCaptureDriver.TimesKey, Arg("-scTimes") ?? "0.3,1.0,1.6,2.4,3.4,4.8");
Debug.Log("[TKS] 시나리오 캡처 시작 → " + dir);
EditorApplication.EnterPlaymode();
}
static string Arg(string name)
{
var args = System.Environment.GetCommandLineArgs();
for (int i = 0; i < args.Length - 1; i++)
if (args[i] == name) return args[i + 1];
return null;
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: f1bc9e1be21ee9644a9b0666e67de178

View File

@ -0,0 +1,136 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace TKS.OutGame
{
/// <summary>
/// 시나리오 이벤트 검증 캡처(2026-11-12 · 개발 요청서 C1·C2) — 에디터 `TKS.EditorTools.ScenarioCapture.Run` 이 SessionState 로 넘기면 생성.
/// ① 스테이지 팝업(전장 설명 칸) ② 보스 스테이지마다 등장 연출을 정해진 시각에 찍고 아군 차례가 되면 1장 더 · 세이브 = 메모리 전용 신규 유저.
/// </summary>
public class ScenarioCaptureDriver : MonoBehaviour
{
public const string DirKey = "TKS_SC_CAPTURE_DIR";
public const string PopupKey = "TKS_SC_CAPTURE_POPUPS";
public const string StagesKey = "TKS_SC_CAPTURE_STAGES";
public const string TimesKey = "TKS_SC_CAPTURE_TIMES";
const int W = 1080, H = 1920;
string dir;
string[] popups = new string[0], stages = new string[0];
float[] times = new float[0];
readonly List<string> log = new List<string>();
#if UNITY_EDITOR
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
static void AutoSpawn()
{
string d = UnityEditor.SessionState.GetString(DirKey, "");
if (string.IsNullOrEmpty(d)) return;
UnityEditor.SessionState.EraseString(DirKey);
var drv = new GameObject("ScenarioCaptureDriver").AddComponent<ScenarioCaptureDriver>();
drv.dir = d;
drv.popups = Split(UnityEditor.SessionState.GetString(PopupKey, ""));
drv.stages = Split(UnityEditor.SessionState.GetString(StagesKey, ""));
var ts = new List<float>();
foreach (var t in Split(UnityEditor.SessionState.GetString(TimesKey, "")))
{
float v;
if (float.TryParse(t, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out v)) ts.Add(v);
}
drv.times = ts.ToArray();
}
#endif
static string[] Split(string s)
{
return s.Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries);
}
static int Index(BattleManager b, string cs)
{
var p = cs.Split('-');
int c, s;
if (p.Length != 2 || !int.TryParse(p[0], out c) || !int.TryParse(p[1], out s)) return -1;
for (int i = 0; i < b.Config.stages.Length; i++)
if (b.Config.stages[i].chapter == c && b.Config.stages[i].stage == s) return i;
return -1;
}
IEnumerator Start()
{
Directory.CreateDirectory(dir);
yield return null;
yield return null;
var root = OutGameRoot.Instance;
var cam = Camera.main;
if (root == null || cam == null)
{
Log("FAIL: OutGameRoot 또는 카메라 없음");
Finish(1);
yield break;
}
var bm = root.Battle;
foreach (var cs in popups)
{
int si = Index(bm, cs.Trim());
if (si < 0) { Log("FAIL: 스테이지 없음 " + cs); continue; }
root.OpenWorldMap();
yield return new WaitForSecondsRealtime(0.4f);
root.Map.Show(bm.Config.stages[si].chapter - 1);
yield return new WaitForSecondsRealtime(0.3f);
root.Map.OpenPopup(bm.Config.stages[si].stage - 1);
yield return new WaitForSecondsRealtime(0.4f);
yield return Shot(cam, "popup_" + cs.Trim());
}
foreach (var cs in stages)
{
int si = Index(bm, cs.Trim());
if (si < 0) { Log("FAIL: 스테이지 없음 " + cs); continue; }
root.Map.EnterStage(bm.Config.stages[si].chapter - 1, bm.Config.stages[si].stage - 1);
float t0 = Time.realtimeSinceStartup;
foreach (var t in times)
{
while (Time.realtimeSinceStartup - t0 < t) yield return null;
yield return Shot(cam, "intro_" + cs.Trim() + "_" + t.ToString("0.0", System.Globalization.CultureInfo.InvariantCulture) + "s");
}
while (bm.Phase != BattlePhase.PlayerTurn && Time.realtimeSinceStartup - t0 < 20f) yield return null;
Log("intro " + cs + " → 아군 차례까지 " + (Time.realtimeSinceStartup - t0).ToString("0.00") + "초 · phase=" + bm.Phase);
yield return new WaitForSecondsRealtime(0.8f);
yield return Shot(cam, "intro_" + cs.Trim() + "_end");
bm.GoIdle();
root.OpenWorldMap();
yield return new WaitForSecondsRealtime(0.5f);
}
Log("scenario errors=" + ScenarioData.Errors.Count);
foreach (var e in ScenarioData.Errors) Log(" " + e);
Finish(0);
}
IEnumerator Shot(Camera cam, string name)
{
string file = Path.Combine(dir, name + ".png");
yield return CaptureUtil.Capture(cam, W, H, file);
Log("shot " + file);
}
void Log(string s)
{
log.Add(s);
Debug.Log("[TKS-SC] " + s);
try { File.WriteAllLines(Path.Combine(dir, "scenario_capture_log.txt"), log.ToArray()); }
catch { }
}
void Finish(int code)
{
Log("finish code=" + code);
#if UNITY_EDITOR
UnityEditor.EditorApplication.Exit(code);
#else
Application.Quit(code);
#endif
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 6f660212e4e21244a91bef91ba5d8a19

View File

@ -183,6 +183,11 @@ namespace TKS.OutGame
// 전투 연결: 출전 = 편성 프리셋 · 결과 = 보상
b.LineupProvider = Session.BuildLineup;
b.StageStarted += () => resultDone = false;
b.StageClearedProvider = (c, st) => // 보스 등장 연출 다시 출정 축약(2026-11-12 시나리오 이벤트 C2)
{
var rec = Session.Save.Stage(c, st, false);
return rec != null && rec.clears > 0;
};
b.PhaseChanged += OnPhase;
// 보물 crit·range·splash = 아군 진영 상시 효과(SkillMods) · 전투 이벤트 카운터(PD #1093 C)
b.SideEffectsProvider = f => f == Faction.Player ? TreasureRules.BattleEffects(Session.Db, Session.Save) : null;
@ -799,8 +804,24 @@ namespace TKS.OutGame
if (!string.IsNullOrEmpty(s.place))
UiKit.Label(field, s.place + (string.IsNullOrEmpty(s.bgTheme) ? "" : " · " + s.bgTheme), 26, soft, TextAnchor.MiddleCenter, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(Pad, -76f), new Vector2(W - Pad * 2f, 34f), false);
// 적 구성 = 병종 원(type 색 Circle78 68 + 병종 아이콘 40) + 「×n」 · 가운데 정렬
// 전장 설명(2026-11-12 시나리오 이벤트 C1 · Resources/Scenario/stage_story.csv) — 장소 줄 아래 · 짙은 칸 + 금색 테두리 · 2줄 이내 · 잠긴 판·다시 출정에도
float y = 124f;
string desc = ScenarioData.Desc(s.chapter, s.stage);
if (!string.IsNullOrEmpty(desc))
{
const float DescH = 84f;
var box = UiKit.Rect("Desc", field, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(Pad, -118f), new Vector2(W - Pad * 2f, DescH));
var bg = UiKit.Skin(box, "panel12", UiKit.Col("row_on_field", UiKit.Dark)); // 별 조건 행과 같은 짙은 칸
bg.raycastTarget = false;
var rim = box.gameObject.AddComponent<Outline>();
rim.effectColor = UiKit.Col("gold", new Color(0.91f, 0.66f, 0.23f));
rim.effectDistance = new Vector2(2f, -2f);
var dt = UiKit.Label(box, desc, 26, UiKit.Col("text_cream", new Color(1f, 0.95f, 0.84f)), TextAnchor.MiddleCenter, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(18f, -4f), new Vector2(W - Pad * 2f - 36f, DescH - 8f), false);
dt.horizontalOverflow = HorizontalWrapMode.Wrap;
y += DescH + 8f;
}
// 적 구성 = 병종 원(type 색 Circle78 68 + 병종 아이콘 40) + 「×n」 · 가운데 정렬
UiKit.SubTitle(field, "적 구성", Pad, y, W - Pad * 2f);
var counts = new int[UnitTypeInfo.Count];
var lead = new List<string>();

View File

@ -235,6 +235,7 @@ namespace TKS
void Begin(BalanceConfig.StageDef stage)
{
StopAllCoroutines();
BossIntro.Abort();
ClearUnits();
Phase = BattlePhase.Setup;
sideEffects[0] = SideEffectsProvider != null ? SideEffectsProvider(Faction.Player) : null;
@ -274,9 +275,15 @@ namespace TKS
string tip = GimmickTables.Table != null ? GimmickTables.Table.TipFor(stage.chapter, stage.stage) : "";
if (tip.Length > 0) LastMessage += " · " + tip; // 1장 튜토리얼 문구(tutorial_tips.csv · PD #1098 §3)
if (StageStarted != null) StageStarted();
SetPhase(BattlePhase.PlayerTurn);
// 보스 등장 연출(2026-11-12 시나리오 이벤트 C2 · boss_intro.csv) — 연출 동안 Setup(아군 조작 잠금) → 끝나면 아군 차례 · 연무장(Mode) 전투 제외
bool cleared = StageClearedProvider != null && StageClearedProvider(stage.chapter, stage.stage);
if (Mode == null && BossIntro.Wants(stage, cleared)) BossIntro.Begin(this, stage, cleared, () => SetPhase(BattlePhase.PlayerTurn));
else SetPhase(BattlePhase.PlayerTurn);
}
/// <summary>이미 깬 스테이지인가(장, 번호) — 보스 등장 연출의 다시 출정 축약(replay_mode) 판정 · 아웃게임 세이브가 넣는다.</summary>
public Func<int, int, bool> StageClearedProvider;
/// <summary>결과 화면 탭 처리기(true = 승리). 있으면 다음 전투로 넘기지 않고 이 처리기(월드맵 복귀)를 부른다.</summary>
public Action<bool> ResultHandler;
@ -284,6 +291,7 @@ namespace TKS
public void GoIdle()
{
StopAllCoroutines();
BossIntro.Abort();
ClearUnits();
SetPhase(BattlePhase.Setup);
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c5e2283276bfdff45af132e9f978e8ca
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,488 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace TKS
{
/// <summary>
/// 보스 스테이지 시작 연출(2026-11-12 PD 「보스는 등장할 때 포커스 + 짤막한 대사(말풍선)」 · 「예시처럼 보스 등장 연출」 · 개발 요청서 C2).
/// ① 경고(위아래 검은 띠 + 붉은 가장자리 깜빡임) → ② 보스 포커스(카메라 이동·확대 · 다른 유닛 어둡게 · 발밑 붉은 원) →
/// ③ 컷인(위 「BOSS 등장!」 붉은 줄무늬 띠 → 보스 전신 + 아래 이름 띠) → ④ 말풍선 대사(타자 효과 · 2인 보스는 n_order 순) → ⑤ 아군 시야로 복귀.
/// 값 = ScenarioData.Cfg(boss_intro_config.csv) · 대사 = boss_intro.csv · 그림 = Resources/Scenario/*.png(띠·글자·말풍선 · 없으면 색 면) + 보스 유닛 그림.
/// 연출 동안 전투 단계 = Setup(아군 조작 잠금) · 끝나면 onDone(아군 차례). Sim.Active(적 AI 가상 실행) 중에는 아무것도 하지 않는다.
/// </summary>
public class BossIntro : MonoBehaviour
{
static BossIntro current;
BattleManager battle;
CameraController cc;
Action onDone;
List<Unit> bosses = new List<Unit>();
List<ScenarioData.BossLine> lines;
bool withCutin;
bool skip;
int taps;
Vector3 camStart;
float viewStart;
readonly Dictionary<SpriteRenderer, Color> dimmed = new Dictionary<SpriteRenderer, Color>();
readonly List<GameObject> rings = new List<GameObject>();
RectTransform root, fx;
Image dim, edge, barTop, barBottom;
Button skipBtn;
static float C(string k)
{
return ScenarioData.Cfg(k);
}
/// <summary>이 스테이지에 연출을 틀지(보스 행 있음 · 가상 실행 아님 · 다시 출정 = replay_mode 2 면 안 틂).</summary>
public static bool Wants(BalanceConfig.StageDef stage, bool cleared)
{
if (Sim.Active || stage == null || stage.kind != StageKind.Boss) return false;
if (ScenarioData.Bosses(stage.chapter, stage.stage).Count == 0) return false;
return !(cleared && Mathf.RoundToInt(C("replay_mode")) == 2);
}
/// <summary>연출 시작 — cleared = 이미 깬 스테이지(replay_mode 1 = 컷인 빼고 ②④⑤).</summary>
public static void Begin(BattleManager battle, BalanceConfig.StageDef stage, bool cleared, Action onDone)
{
Abort();
var cc = FindFirstObjectByType<CameraController>();
if (cc == null || cc.Cam == null)
{
onDone?.Invoke();
return;
}
var go = new GameObject("BossIntroUI");
var bi = go.AddComponent<BossIntro>();
current = bi;
bi.battle = battle;
bi.cc = cc;
bi.onDone = onDone;
bi.lines = ScenarioData.Bosses(stage.chapter, stage.stage);
bi.withCutin = !(cleared && Mathf.RoundToInt(C("replay_mode")) == 1);
foreach (var l in bi.lines)
{
Unit hit = null;
foreach (var u in battle.AliveUnits(Faction.Enemy))
if (u.IsBoss && u.ArtId == l.id) { hit = u; break; }
if (hit == null)
foreach (var u in battle.AliveUnits(Faction.Enemy))
if (u.IsBoss && !bi.bosses.Contains(u)) { hit = u; break; }
bi.bosses.Add(hit);
}
bi.Build();
bi.StartCoroutine(bi.Run());
}
/// <summary>진행 중 연출을 바로 치움(전투 재시작 · 월드맵 복귀) — 어둡게·원·카메라 상태를 되돌린다.</summary>
public static void Abort()
{
if (current == null) return;
current.Restore();
Destroy(current.gameObject);
current = null;
}
// ---------- 화면 ----------
static Sprite Spr(string name)
{
return Resources.Load<Sprite>(ScenarioData.Root + name);
}
static RectTransform Rt(string name, Transform parent, Vector2 aMin, Vector2 aMax, Vector2 pivot, Vector2 pos, Vector2 size)
{
var go = new GameObject(name, typeof(RectTransform));
go.transform.SetParent(parent, false);
var rt = (RectTransform)go.transform;
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, Color col, Vector2 aMin, Vector2 aMax, Vector2 pivot, Vector2 pos, Vector2 size)
{
var img = Rt(name, parent, aMin, aMax, pivot, pos, size).gameObject.AddComponent<Image>();
img.sprite = sp;
img.color = col;
img.raycastTarget = false;
return img;
}
static Image Full(string name, Transform parent, Sprite sp, Color col)
{
return Img(name, parent, sp, col, Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f), Vector2.zero, Vector2.zero);
}
static Text Txt(Transform parent, string s, int size, Color col, TextAnchor anchor, Vector2 pos, Vector2 box, Font font)
{
var t = Rt("Text", parent, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), pos, box).gameObject.AddComponent<Text>();
t.font = font;
t.fontSize = size;
t.color = col;
t.alignment = anchor;
t.text = s;
t.supportRichText = false;
t.raycastTarget = false;
t.horizontalOverflow = HorizontalWrapMode.Wrap;
t.verticalOverflow = VerticalWrapMode.Overflow;
return t;
}
static void Stroke(Text t, Color col, float d)
{
var o = t.gameObject.AddComponent<Outline>();
o.effectColor = col;
o.effectDistance = new Vector2(d, -d);
var o2 = t.gameObject.AddComponent<Outline>();
o2.effectColor = col;
o2.effectDistance = new Vector2(-d, d);
}
void Build()
{
UiLayer.Root(gameObject, cc.Cam, 460, 0.38f, UiLayer.Reference, UiRate.Event); // 아웃게임 위 덮개(재화 바 · 450)보다 위 · 연출 동안 화면 전체를 덮음
root = (RectTransform)transform;
// 누름 받이(탭 1 = 대사 전부 · 탭 2 = 닫기) — 전체 화면 · 투명
var catcher = Full("Tap", root, null, new Color(0f, 0f, 0f, 0f));
catcher.raycastTarget = true;
catcher.gameObject.AddComponent<Button>().onClick.AddListener(() => taps++);
// 움직이는 것 = Frame 층 하나에 모음(UI 캔버스 규칙)
fx = UiLayer.Group("Fx", root, UiRate.Frame);
dim = Full("Dim", fx, null, new Color(0f, 0f, 0f, 0f));
edge = Full("Edge", fx, Spr("warn_edge"), new Color(1f, 1f, 1f, 0f));
float bar = UiLayer.Reference.y * C("letterbox_ratio");
barTop = Img("BarTop", fx, null, Color.black, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0.5f, 0f), Vector2.zero, new Vector2(0f, bar));
barBottom = Img("BarBottom", fx, null, Color.black, new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(0.5f, 1f), Vector2.zero, new Vector2(0f, bar));
// 건너뛰기(오른쪽 위 · skip_show_after_sec 뒤 보임)
var sb = Img("Skip", root, null, new Color(0f, 0f, 0f, 0.6f), new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-40f, -60f), new Vector2(190f, 80f));
sb.raycastTarget = true;
skipBtn = sb.gameObject.AddComponent<Button>();
skipBtn.onClick.AddListener(() => skip = true);
Txt(sb.transform, "건너뛰기 >>", 34, Color.white, TextAnchor.MiddleCenter, Vector2.zero, new Vector2(190f, 80f), UISkin.TitleFont);
sb.gameObject.SetActive(false);
}
// ---------- 흐름 ----------
IEnumerator Run()
{
camStart = cc.transform.position;
viewStart = cc.ViewHeight;
StartCoroutine(SkipButtonLater());
yield return Warn();
if (!skip) yield return Focus(Target(0), C("focus_move_sec"), true);
if (!skip && withCutin) yield return Cutin();
for (int i = 0; i < lines.Count && !skip; i++)
{
if (i > 0) yield return Focus(Target(i), C("second_boss_move_sec"), false);
if (!skip) yield return Bubble(i);
}
yield return Return();
Finish();
}
IEnumerator SkipButtonLater()
{
float t = 0f, show = C("skip_show_after_sec");
while (t < show) { t += Time.unscaledDeltaTime; yield return null; }
if (skipBtn != null) skipBtn.gameObject.SetActive(true);
}
Vector2 Target(int i)
{
var u = i < bosses.Count ? bosses[i] : null;
return u != null ? u.Position : (Vector2)camStart;
}
static float Ease(float k)
{
k = Mathf.Clamp01(k);
return k * k * (3f - 2f * k);
}
IEnumerator Warn()
{
float dur = C("warn_sec"), bar = barTop.rectTransform.sizeDelta.y;
int blinks = Mathf.Max(1, Mathf.RoundToInt(C("warn_blink_count")));
for (float t = 0f; t < dur && !skip; t += Time.unscaledDeltaTime)
{
float k = t / dur;
float y = bar * Ease(k);
barTop.rectTransform.anchoredPosition = new Vector2(0f, -y);
barBottom.rectTransform.anchoredPosition = new Vector2(0f, y);
edge.color = new Color(1f, 1f, 1f, Mathf.Abs(Mathf.Sin(k * blinks * Mathf.PI)));
yield return null;
}
barTop.rectTransform.anchoredPosition = new Vector2(0f, -bar);
barBottom.rectTransform.anchoredPosition = new Vector2(0f, bar);
edge.color = new Color(1f, 1f, 1f, 0f);
}
IEnumerator Focus(Vector2 target, float dur, bool first)
{
Vector2 p0 = cc.transform.position;
float h0 = cc.ViewHeight, h1 = viewStart * C("focus_view_ratio");
if (first) DimAndRing();
for (float t = 0f; t < dur && !skip; t += Time.unscaledDeltaTime)
{
float k = Ease(t / dur);
cc.SetViewHeight(Mathf.Lerp(h0, h1, k));
cc.SnapTo(Vector2.Lerp(p0, target, k));
yield return null;
}
cc.SetViewHeight(h1);
cc.SnapTo(target);
}
void DimAndRing()
{
float d = C("dim_others");
var all = new List<Unit>(battle.AliveUnits(Faction.Player));
all.AddRange(battle.AliveUnits(Faction.Enemy));
foreach (var u in all)
{
if (bosses.Contains(u)) continue;
foreach (var sr in u.GetComponentsInChildren<SpriteRenderer>())
{
if (dimmed.ContainsKey(sr)) continue;
dimmed[sr] = sr.color;
var c = sr.color;
sr.color = new Color(c.r * (1f - d), c.g * (1f - d), c.b * (1f - d), c.a);
}
}
foreach (var b in bosses)
{
if (b == null) continue;
var ring = ProceduralSprites.NewSprite(b.transform, "BossRing", ProceduralSprites.Ring, new Color(0.9f, 0.15f, 0.1f, 0.9f), b.Radius * 2f * C("focus_ring_scale"), -1);
rings.Add(ring.gameObject);
}
}
IEnumerator Cutin()
{
var g = Rt("Cutin", fx, Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f), Vector2.zero, Vector2.zero);
var bandTopSp = Spr("cutin_band_top");
var bandBotSp = Spr("cutin_band_bottom");
float W = UiLayer.Reference.x;
float topH = bandTopSp != null ? W * bandTopSp.rect.height / bandTopSp.rect.width : 420f;
float botH = bandBotSp != null ? W * bandBotSp.rect.height / bandBotSp.rect.width : 460f;
var top = Img("BandTop", g, bandTopSp, bandTopSp != null ? Color.white : new Color(0.7f, 0.1f, 0.08f), new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0.5f, 1f), new Vector2(-W, 0f), new Vector2(0f, topH));
// 「BOSS 등장!」 = 위 띠와 같은 크기의 그림(글자 자리 그대로) · 피벗 = 그림의 피벗(글자 가운데) → 찍힘 확대가 글자 가운데 기준
var titleSp = Spr("cutin_title");
var title = Full("Title", top.transform, titleSp, titleSp != null ? Color.white : new Color(1f, 0.8f, 0.3f, 0f));
if (titleSp != null)
{
var piv = new Vector2(titleSp.pivot.x / titleSp.rect.width, titleSp.pivot.y / titleSp.rect.height);
title.rectTransform.pivot = piv;
title.rectTransform.anchoredPosition = Vector2.zero;
title.rectTransform.offsetMin = title.rectTransform.offsetMax = Vector2.zero;
}
var bottom = Img("BandBottom", g, bandBotSp, bandBotSp != null ? Color.white : new Color(0.6f, 0.08f, 0.06f), new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(0.5f, 0f), new Vector2(W, 0f), new Vector2(0f, botH));
// 보스 그림(1인 = cutin_art_height · 2인 = 좌우 각 cutin_art_height_duo)
int n = Mathf.Max(1, bosses.Count);
float artH = UiLayer.Reference.y * (n > 1 ? C("cutin_art_height_duo") : C("cutin_art_height"));
var arts = new List<RectTransform>();
var names = new List<string>();
var titles = new List<string>();
for (int i = 0; i < bosses.Count; i++)
{
var u = bosses[i];
names.Add(u != null ? u.DisplayName : lines[i].id);
titles.Add(lines[i].title);
Sprite sp = u != null ? Resources.Load<Sprite>("Units/" + u.ArtId + "/front_action/f000") : null;
float aw = sp != null ? artH * sp.rect.width / sp.rect.height : artH * 0.8f;
float cx = n > 1 ? (i == 0 ? -W * 0.22f : W * 0.22f) : 40f;
var art = Img("Art" + i, g, sp, sp != null ? Color.white : new Color(0.85f, 0.3f, 0.2f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(cx + W, 60f), new Vector2(aw, artH));
arts.Add(art.rectTransform);
}
// 아래 띠 글자 = 칭호(작게) · 이름(크게) · WARNING!!!(그림)
// 이름 묶음 자리 = 아래 띠 그림의 이름 칸(그림 아래에서 47 % · 가운데에서 왼쪽 20 · 부품 그림 기준 배치)
var info = Rt("Info", bottom.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0.5f, 0.5f), new Vector2(-20f, botH * 0.47f), new Vector2(W, botH));
info.localRotation = Quaternion.Euler(0f, 0f, C("cutin_band_angle"));
var tt = Txt(info, string.Join(" · ", titles.ToArray()), 52, new Color(1f, 0.92f, 0.82f), TextAnchor.MiddleCenter, new Vector2(0f, 118f), new Vector2(W, 70f), UISkin.TitleFont);
Stroke(tt, new Color(0.31f, 0.05f, 0.04f), 3f);
var nm = Txt(info, string.Join(" · ", names.ToArray()), n > 1 ? 120 : 150, Color.white, TextAnchor.MiddleCenter, new Vector2(0f, 10f), new Vector2(W, 170f), UISkin.TitleFont);
Stroke(nm, new Color(0.47f, 0.04f, 0.04f), 6f);
var sh = nm.gameObject.AddComponent<Shadow>();
sh.effectColor = new Color(0.9f, 0.16f, 0.08f, 0.8f);
sh.effectDistance = new Vector2(0f, -8f);
var warnSp = Spr("cutin_warning");
var warn = Img("Warning", info, warnSp, warnSp != null ? Color.white : new Color(1f, 0.85f, 0.4f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, -110f), warnSp != null ? new Vector2(warnSp.rect.width, warnSp.rect.height) * 0.9f : new Vector2(360f, 60f));
// 들어옴 — 어둡게 → 위 띠(왼쪽 밖에서) + 글자 찍힘 → 지연 → 보스(오른쪽에서)·아래 띠
float dark = C("cutin_bg_dark"), bIn = C("cutin_banner_in_sec"), pop = C("cutin_banner_pop_scale");
for (float t = 0f; t < bIn && !skip; t += Time.unscaledDeltaTime)
{
float k = Ease(t / bIn);
dim.color = new Color(0f, 0f, 0f, dark * k);
top.rectTransform.anchoredPosition = new Vector2(Mathf.Lerp(-W, 0f, k), 0f);
title.rectTransform.localScale = Vector3.one * Mathf.Lerp(pop, 1f, k);
yield return null;
}
dim.color = new Color(0f, 0f, 0f, dark);
top.rectTransform.anchoredPosition = Vector2.zero;
title.rectTransform.localScale = Vector3.one;
yield return Wait(C("cutin_info_delay_sec"));
float aIn = C("cutin_in_sec");
for (float t = 0f; t < aIn && !skip; t += Time.unscaledDeltaTime)
{
float k = Ease(t / aIn);
for (int i = 0; i < arts.Count; i++)
{
float cx = n > 1 ? (i == 0 ? -W * 0.22f : W * 0.22f) : 40f;
arts[i].anchoredPosition = new Vector2(Mathf.Lerp(cx + W, cx, k), 60f);
}
bottom.rectTransform.anchoredPosition = new Vector2(Mathf.Lerp(W, 0f, k), 0f);
yield return null;
}
for (int i = 0; i < arts.Count; i++) arts[i].anchoredPosition = new Vector2(n > 1 ? (i == 0 ? -W * 0.22f : W * 0.22f) : 40f, 60f);
bottom.rectTransform.anchoredPosition = Vector2.zero;
cc.Shake(C("cutin_shake_sec"), C("cutin_shake"));
yield return Wait(C("cutin_hold_sec"));
// 빠짐 — 왼쪽 위로 밀려 나가며 흐려짐
var cg = g.gameObject.AddComponent<CanvasGroup>();
float outT = C("cutin_out_sec");
for (float t = 0f; t < outT && !skip; t += Time.unscaledDeltaTime)
{
float k = Ease(t / outT);
cg.alpha = 1f - k;
g.anchoredPosition = new Vector2(-W * 0.25f * k, 0f);
dim.color = new Color(0f, 0f, 0f, dark * (1f - k));
yield return null;
}
dim.color = new Color(0f, 0f, 0f, 0f);
Destroy(g.gameObject);
}
IEnumerator Bubble(int i)
{
var u = i < bosses.Count ? bosses[i] : null;
var l = lines[i];
if (u == null || string.IsNullOrEmpty(l.line)) yield break;
float fs = C("bubble_font_size");
var bub = Img("Bubble", fx, Spr("bubble"), Color.white, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0f), Vector2.zero, new Vector2(640f, fs * 2f * 1.35f + 80f));
bub.type = Image.Type.Sliced;
var tail = Img("Tail", bub.transform, Spr("bubble_tail"), Color.white, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0.5f, 1f), new Vector2(0f, 4f), new Vector2(54f, 40f));
var tag = Img("NameTag", bub.transform, Spr("name_tag"), new Color(0.75f, 0.16f, 0.12f), new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(0f, 0.5f), new Vector2(24f, 0f), new Vector2(0f, 52f));
tag.type = Image.Type.Sliced;
var tagText = Txt(tag.transform, u.DisplayName, 30, Color.white, TextAnchor.MiddleCenter, Vector2.zero, new Vector2(200f, 52f), UISkin.TitleFont);
tag.rectTransform.sizeDelta = new Vector2(tagText.preferredWidth + 44f, 52f);
tagText.rectTransform.sizeDelta = tag.rectTransform.sizeDelta;
var body = Txt(bub.transform, "", Mathf.RoundToInt(fs), new Color(0.24f, 0.13f, 0.07f), TextAnchor.MiddleCenter, new Vector2(0f, -4f), new Vector2(580f, fs * 2f * 1.35f + 20f), UISkin.TitleFont);
float popT = C("bubble_pop_sec"), from = C("bubble_pop_from"), peak = C("bubble_pop_peak");
taps = 0;
for (float t = 0f; t < popT && !skip; t += Time.unscaledDeltaTime)
{
float k = t / popT;
bub.rectTransform.localScale = Vector3.one * (k < 0.7f ? Mathf.Lerp(from, peak, k / 0.7f) : Mathf.Lerp(peak, 1f, (k - 0.7f) / 0.3f));
Place(bub.rectTransform, tail.rectTransform, u);
yield return null;
}
bub.rectTransform.localScale = Vector3.one;
float cps = Mathf.Max(1f, C("bubble_char_per_sec"));
float shown = 0f;
while (shown < l.line.Length && !skip && taps == 0)
{
shown += cps * Time.unscaledDeltaTime;
body.text = l.line.Substring(0, Mathf.Min(l.line.Length, Mathf.FloorToInt(shown)));
Place(bub.rectTransform, tail.rectTransform, u);
yield return null;
}
body.text = l.line;
if (taps > 0) taps = 0; // 탭 1 = 전부 표시 · 다음 탭 = 닫기
float hold = C("bubble_hold_sec");
for (float t = 0f; t < hold && !skip && taps == 0; t += Time.unscaledDeltaTime)
{
Place(bub.rectTransform, tail.rectTransform, u);
yield return null;
}
var cg = bub.gameObject.AddComponent<CanvasGroup>();
float fade = C("bubble_fade_sec");
for (float t = 0f; t < fade && !skip; t += Time.unscaledDeltaTime)
{
cg.alpha = 1f - t / fade;
yield return null;
}
Destroy(bub.gameObject);
}
/// <summary>말풍선 = 보스 머리 위 · 화면 밖이면 안쪽으로 밀어 넣고 꼬리만 보스를 따라감.</summary>
void Place(RectTransform bub, RectTransform tail, Unit u)
{
var cam = cc.Cam;
Vector2 head = u.Position + new Vector2(0f, u.Radius * 1.6f);
Vector2 screen = RectTransformUtility.WorldToScreenPoint(cam, head);
Vector2 local;
RectTransformUtility.ScreenPointToLocalPointInRectangle(root, screen, cam, out local);
var half = root.rect.size * 0.5f;
var size = bub.sizeDelta;
float x = Mathf.Clamp(local.x, -half.x + size.x * 0.5f + 20f, half.x - size.x * 0.5f - 20f);
float y = Mathf.Clamp(local.y + 40f, -half.y + 40f, half.y - size.y - 40f);
var p = new Vector2(x, y);
if (bub.anchoredPosition != p) bub.anchoredPosition = p;
var tp = new Vector2(Mathf.Clamp(local.x - x, -size.x * 0.5f + 40f, size.x * 0.5f - 40f), 4f);
if (tail.anchoredPosition != tp) tail.anchoredPosition = tp;
}
IEnumerator Return()
{
Restore();
float dur = C("return_sec");
Vector2 p0 = cc.transform.position;
float h0 = cc.ViewHeight, bar = barTop.rectTransform.sizeDelta.y;
float a0 = dim.color.a;
for (float t = 0f; t < dur; t += Time.unscaledDeltaTime)
{
float k = Ease(t / dur);
cc.SetViewHeight(Mathf.Lerp(h0, viewStart, k));
cc.SnapTo(Vector2.Lerp(p0, camStart, k));
barTop.rectTransform.anchoredPosition = new Vector2(0f, -bar * (1f - k));
barBottom.rectTransform.anchoredPosition = new Vector2(0f, bar * (1f - k));
dim.color = new Color(0f, 0f, 0f, a0 * (1f - k));
yield return null;
}
cc.SetViewHeight(viewStart);
}
IEnumerator Wait(float sec)
{
for (float t = 0f; t < sec && !skip; t += Time.unscaledDeltaTime) yield return null;
}
void Restore()
{
foreach (var kv in dimmed)
if (kv.Key != null) kv.Key.color = kv.Value;
dimmed.Clear();
foreach (var r in rings)
if (r != null) Destroy(r);
rings.Clear();
}
void Finish()
{
var done = onDone;
onDone = null;
if (current == this) current = null;
Destroy(gameObject);
done?.Invoke();
}
void OnDestroy()
{
Restore();
if (current == this) current = null;
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 3a2c0313612ca0949b1cdba6f9b1c7db

View File

@ -0,0 +1,162 @@
using System.Collections.Generic;
using System.Globalization;
using UnityEngine;
namespace TKS
{
/// <summary>
/// 시나리오 이벤트 표(2026-11-12 PD 「스테이지 선택 때 전장 설명 · 보스 등장 포커스 + 대사 + 등장 연출」 · 개발 요청서 C1·C2).
/// SOT = 조직 레포 `공유/기획팀_산출물/삼국지슬링샷/tables/` → 사본 `Assets/Resources/Scenario/*.csv`(utf-8-sig · 고친 뒤 기획 tables 도 같이).
/// stage_story.csv = n_chapter,n_stage,s_desc_ko,Memo · boss_intro.csv = n_chapter,n_stage,n_order,s_boss_id,s_title_ko,s_line_ko,Memo ·
/// boss_intro_config.csv = s_key,f_value,Memo — 값은 전부 표에서 읽는다(C45 · 코드에 값 없음).
/// </summary>
public static class ScenarioData
{
public const string Root = "Scenario/";
public class BossLine
{
public int chapter;
public int stage;
public int order;
public string id;
public string title;
public string line;
}
static bool loaded;
static readonly Dictionary<long, string> desc = new Dictionary<long, string>();
static readonly List<BossLine> bosses = new List<BossLine>();
static readonly Dictionary<string, float> cfg = new Dictionary<string, float>();
static readonly HashSet<string> missingReported = new HashSet<string>();
/// <summary>읽기 오류(형식 · 빠진 칸 · 없는 키) — 데이터 검사 테스트가 0 인지 본다.</summary>
public static readonly List<string> Errors = new List<string>();
public static void Reload()
{
loaded = false;
Load();
}
static void Load()
{
if (loaded) return;
loaded = true;
desc.Clear();
bosses.Clear();
cfg.Clear();
Errors.Clear();
missingReported.Clear();
foreach (var r in Rows("stage_story"))
{
int c = Int(r, "n_chapter", "stage_story"), s = Int(r, "n_stage", "stage_story");
desc[Key(c, s)] = Get(r, "s_desc_ko");
}
foreach (var r in Rows("boss_intro"))
{
bosses.Add(new BossLine
{
chapter = Int(r, "n_chapter", "boss_intro"),
stage = Int(r, "n_stage", "boss_intro"),
order = Int(r, "n_order", "boss_intro"),
id = Get(r, "s_boss_id"),
title = Get(r, "s_title_ko"),
line = Get(r, "s_line_ko"),
});
}
bosses.Sort((a, b) => a.chapter != b.chapter ? a.chapter.CompareTo(b.chapter) : a.stage != b.stage ? a.stage.CompareTo(b.stage) : a.order.CompareTo(b.order));
foreach (var r in Rows("boss_intro_config"))
{
float v;
if (float.TryParse(Get(r, "f_value"), NumberStyles.Float, CultureInfo.InvariantCulture, out v)) cfg[Get(r, "s_key")] = v;
else Errors.Add("boss_intro_config.csv 행 " + Get(r, "#") + ": f_value 숫자 아님");
}
foreach (var e in Errors) Debug.LogError("[TKS] 시나리오 표 " + e);
}
static List<Dictionary<string, string>> Rows(string file)
{
var ta = Resources.Load<TextAsset>(Root + file);
if (ta == null)
{
Errors.Add("Resources/" + Root + file + ".csv 없음");
return new List<Dictionary<string, string>>();
}
return StageTable.ReadCsv(ta.text, file + ".csv", Errors);
}
static long Key(int chapter, int stage)
{
return chapter * 1000L + stage;
}
static string Get(Dictionary<string, string> r, string k)
{
string v;
return r.TryGetValue(k, out v) ? v : "";
}
static int Int(Dictionary<string, string> r, string k, string file)
{
int v;
if (int.TryParse(Get(r, k), NumberStyles.Integer, CultureInfo.InvariantCulture, out v)) return v;
Errors.Add(file + ".csv 행 " + Get(r, "#") + ": " + k + " 정수 아님");
return 0;
}
/// <summary>스테이지 선택 팝업의 전장 설명(없으면 "").</summary>
public static string Desc(int chapter, int stage)
{
Load();
string s;
return desc.TryGetValue(Key(chapter, stage), out s) ? s : "";
}
/// <summary>그 스테이지의 보스 등장 행(n_order 순 · 없으면 빈 목록).</summary>
public static List<BossLine> Bosses(int chapter, int stage)
{
Load();
return bosses.FindAll(b => b.chapter == chapter && b.stage == stage);
}
public static IList<BossLine> AllBosses
{
get
{
Load();
return bosses;
}
}
public static IEnumerable<KeyValuePair<long, string>> AllDesc
{
get
{
Load();
return desc;
}
}
/// <summary>연출 값(boss_intro_config.csv) — 키가 없으면 콘솔 오류 1회 + 0.</summary>
public static float Cfg(string key)
{
Load();
float v;
if (cfg.TryGetValue(key, out v)) return v;
if (missingReported.Add(key))
{
Errors.Add("boss_intro_config.csv 에 키 없음: " + key);
Debug.LogError("[TKS] boss_intro_config.csv 에 키 없음: " + key);
}
return 0f;
}
public static bool HasCfg(string key)
{
Load();
return cfg.ContainsKey(key);
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: f2b4808b701e4c3479c7d156ada75174

View File

@ -633,6 +633,8 @@ namespace TKS
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>");
string desc = ScenarioData.Desc(stage.chapter, stage.stage); // 전장 설명(2026-11-12 시나리오 이벤트 C1)
if (desc.Length > 0) body.Append("\n<size=26>").Append(desc).Append("</size>");
body.Append("\n\n").Append(EnemySummary(stage));
if (PopupInfo != null)
{
@ -763,7 +765,7 @@ namespace TKS
// 팩 스테이지 팝업 배치(UI px · 패널 왼쪽 위 기준 · #1104)
const float PopupW = 900f;
const float PopupH = 1160f;
const float PopupH = 1252f; // 1160 + 전장 설명 칸 92(2026-11-12 시나리오 이벤트 C1)
const float PopupBtnY = PopupH - 52f - 104f;
void BuildPopup()

View File

@ -0,0 +1,78 @@
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
namespace TKS.Tests
{
/// <summary>
/// 시나리오 이벤트 표(2026-11-12 · 개발 요청서 C1·C2) 데이터 검사 — 전장 설명 = 스테이지와 1:1 · 50자 이하 · 본문 폰트에 없는 글자 없음 /
/// 보스 등장 행 = 보스 스테이지의 보스 무장과 1:1 · 대사 ≤ bubble_max_chars / 연출 값 표 읽기 오류 0.
/// </summary>
public class ScenarioDataTests
{
const string BadGlyphs = "—「」…"; // 넥슨 Lv1 고딕에 없는 글자(기획 검사와 같은 목록)
static BalanceConfig Cfg()
{
var c = Resources.Load<BalanceConfig>("BalanceConfig");
Assert.IsNotNull(c, "Resources/BalanceConfig 없음");
return c;
}
[Test]
public void StageStory_OnePerStage_ShortAndFontSafe()
{
ScenarioData.Reload();
var cfg = Cfg();
int n = 0;
foreach (var kv in ScenarioData.AllDesc) n++;
Assert.AreEqual(cfg.stages.Length, n, "전장 설명 행 수 ≠ 스테이지 수");
foreach (var s in cfg.stages)
{
string d = ScenarioData.Desc(s.chapter, s.stage);
Assert.IsNotEmpty(d, s.chapter + "-" + s.stage + " 전장 설명 없음");
Assert.LessOrEqual(d.Length, 50, s.chapter + "-" + s.stage + " 50자 초과");
Assert.AreEqual(-1, d.IndexOfAny(BadGlyphs.ToCharArray()), s.chapter + "-" + s.stage + " 폰트 없는 글자");
}
Assert.AreEqual(0, ScenarioData.Errors.Count, string.Join("\n", ScenarioData.Errors.ToArray()));
}
[Test]
public void BossIntro_MatchesBossGenerals_LinesFit()
{
ScenarioData.Reload();
var cfg = Cfg();
int maxChars = Mathf.RoundToInt(ScenarioData.Cfg("bubble_max_chars"));
Assert.Greater(maxChars, 0, "bubble_max_chars 없음");
int rows = 0;
foreach (var s in cfg.stages)
{
var want = new List<string>();
foreach (var e in s.enemies)
if (e.isBoss) want.Add(e.art);
var got = new List<string>();
foreach (var b in ScenarioData.Bosses(s.chapter, s.stage))
{
got.Add(b.id);
Assert.IsNotEmpty(b.title, s.chapter + "-" + s.stage + " 칭호 없음");
Assert.IsNotEmpty(b.line, s.chapter + "-" + s.stage + " 대사 없음");
Assert.LessOrEqual(b.line.Length, maxChars, s.chapter + "-" + s.stage + " 대사 " + b.line.Length + "자");
rows++;
}
want.Sort();
got.Sort();
CollectionAssert.AreEqual(want, got, s.chapter + "-" + s.stage + " 보스 행 ≠ 보스 무장");
}
Assert.AreEqual(ScenarioData.AllBosses.Count, rows, "보스 등장 표에 없는 스테이지 행이 있음");
}
[Test]
public void IntroConfig_ReadsWithoutErrors()
{
ScenarioData.Reload();
foreach (var k in new[] { "warn_sec", "focus_move_sec", "cutin_hold_sec", "bubble_char_per_sec", "return_sec", "replay_mode" })
Assert.IsTrue(ScenarioData.HasCfg(k), "연출 값 키 없음: " + k);
Assert.AreEqual(0, ScenarioData.Errors.Count, string.Join("\n", ScenarioData.Errors.ToArray()));
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 42f3ebf4ba57f6248935982df0958343