편성 화면 비주얼 개선 = Fable 제안서 §3 구현(#1104 · PD 2026-11-09 「프레임 구분 · 디자인 요소 · 카피바라GO·탕탕특공대 조사 → Fable 제안·검토」)
- 섹션 패널 2개(출전 편성 · 보유 영웅) + 바탕 홈 16 = 그림자 → 프레임 #3F4262 → 필드 #262840(마스크) → 문양 타일 5 %(A) → 바닥 그라데이션(A · Glow_Panel01 뒤집기 · 실측 = 위 불투명) → 윗면 광택 - 제목 띠 Title_Tapered02 #121A33 + 수량 뱃지 · 제약 칩(ⓘ = 편성 안내 팝업 · 안내 문장 이관) · 저장 = 녹 Secondary(바뀐 것 없으면 비활성 색 · 바뀌면 알림 점) · 프리셋 탭 + 출전 꼬리 칩 · 총 전투력 칩 - 전열/후열 밴드(흰 6 %) + 구분선 + 평행사변형 칩 · 자리 받침(#1A1C2E + 광택) · 자리 카드 × 0.62 · 빈 자리 = 원본 빈 카드 + 초록 플러스 뱃지 · 선택 = FocusLine 노랑 깜빡(UiPulse) - 보유 목록: 「장수 ▼」 칩 · 출전 중 = 꼬리 칩 + 35 % 덮개 + 초록 체크 뱃지 · 위·아래 스크롤 페이드 - UiKit.SectionPanel / SectionTitle / ScrollFades(다른 화면 공용) · 테마 행 26 테스트 117/117 · console error 0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
939275d105
commit
323658a91d
|
|
@ -382,4 +382,30 @@ color,subtab_off,,,,,,#36364E,서브탭 꺼짐(팩)
|
||||||
color,row_front,,,,,,#D8412F,편성 전열 칩
|
color,row_front,,,,,,#D8412F,편성 전열 칩
|
||||||
color,row_back,,,,,,#2C6CE0,편성 후열 칩
|
color,row_back,,,,,,#2C6CE0,편성 후열 칩
|
||||||
color,select_line,,,,,,#FFE45C,편성 자리 선택 테두리
|
color,select_line,,,,,,#FFE45C,편성 자리 선택 테두리
|
||||||
|
color,panel_frame,,,,,,#3F4262,섹션 패널 프레임(바탕보다 밝게 · Fable 제안서 §3-6)
|
||||||
|
color,panel_field,,,,,,#262840,섹션 패널 안쪽 필드(바탕보다 어둡게)
|
||||||
|
color,panel_light,,,,,,#FFFFFF1A,섹션 패널 윗면 광택(흰 10 %)
|
||||||
|
color,panel_shadow,,,,,,#14121A59,섹션 패널 그림자(α 0.35 · 아래 6)
|
||||||
|
color,panel_pattern,,,,,,#FFFFFF0D,섹션 패널 문양 타일(흰 5 %)
|
||||||
|
color,panel_ground,,,,,,#0000002E,섹션 패널 바닥 그라데이션(검정 18 %)
|
||||||
|
color,band_title,,,,,,#121A33,섹션 제목 띠(Title_Tapered02 틴트)
|
||||||
|
color,row_band,,,,,,#FFFFFF0F,편성 전열·후열 밴드(흰 6 %)
|
||||||
|
color,divider,,,,,,#FFFFFF40,구분선(흰 25 %)
|
||||||
|
color,seat_plate,,,,,,#1A1C2EE6,편성 자리 받침(α 0.9)
|
||||||
|
color,seat_light,,,,,,#FFFFFF14,편성 자리 받침 윗면 광택(흰 8 %)
|
||||||
|
color,seat_dim,,,,,,#00000059,출전 중 카드 덮개(35 %)
|
||||||
|
skin,panel_frame,Frame/BorderFrame_Round20_White_Bg.png,,1,,,,섹션 패널 프레임(틴트)
|
||||||
|
skin,panel_field,Frame/BasicFrame_Round20.png,,1,,,,섹션 패널 필드(틴트)
|
||||||
|
skin,panel_light,Frame/BorderFrame_Round20_White_Light.png,,1,,,,섹션 패널 윗면 광택
|
||||||
|
skin,band_title,Label/Title_Tapered02.png,,1,,,,섹션 제목 띠(틴트)
|
||||||
|
skin,row_band,Frame/BasicFrame_Round12.png,,0.625,,,,편성 열 밴드
|
||||||
|
skin,divider,Label/Title_Line03_Divider.png,,1,,,,구분선(틴트)
|
||||||
|
skin,seat_plate,Frame/BasicFrame_Round12.png,,0.625,,,,편성 자리 받침
|
||||||
|
skin,focus_line,Frame/ItemFrame00~03_FocusLine.png,,1,,,,선택 테두리(틴트)
|
||||||
|
skin,badge_circle,UI_Etc/Alert_Circle_s_Bg.png,,1,,,,작은 원 뱃지(수량·플러스 바탕)
|
||||||
|
skin,check_circle,Frame/BorderFrame_Circle75_Bg.png,,1,,,,체크 뱃지 원
|
||||||
|
skin,scroll_fade,Assets/UI/GUIPro/ResourcesData/Sprites/Demo/Demo_Background/Glow_Panel01.png,,1,,,,스크롤 페이드·바닥 그라데이션(위 불투명 → 아래 투명 · 실측)
|
||||||
|
skin,btn_s_green,Button/Button01_s_Green.png,Button/Button01_s_White_Light1.png,1.8,4;3;4;10,0.35,,Secondary 녹(편성 저장) + 광택
|
||||||
|
icon,plus_glyph,UI_Etc/ResourceBar_Single_Btn_Yellow2.png,,,,,,플러스 글리프(빈 자리 뱃지)
|
||||||
|
icon,check_badge,IconMisc/Icon_Check01.png,,,,,,체크(출전 중 뱃지)
|
||||||
font,title,Assets/UI/GUIPro/ResourcesData/Fonts/Sen-ExtraBold.ttf,,,,,,제목·숫자(라틴 Sen · 한글 = 폴백 Malgun Gothic · PD 결정 전)
|
font,title,Assets/UI/GUIPro/ResourcesData/Fonts/Sen-ExtraBold.ttf,,,,,,제목·숫자(라틴 Sen · 한글 = 폴백 Malgun Gothic · PD 결정 전)
|
||||||
|
|
|
||||||
|
|
|
@ -467,6 +467,30 @@ MonoBehaviour:
|
||||||
color: {r: 0.17254902, g: 0.42352942, b: 0.8784314, a: 1}
|
color: {r: 0.17254902, g: 0.42352942, b: 0.8784314, a: 1}
|
||||||
- id: select_line
|
- id: select_line
|
||||||
color: {r: 1, g: 0.89411765, b: 0.36078432, a: 1}
|
color: {r: 1, g: 0.89411765, b: 0.36078432, a: 1}
|
||||||
|
- id: panel_frame
|
||||||
|
color: {r: 0.24705882, g: 0.25882354, b: 0.38431373, a: 1}
|
||||||
|
- id: panel_field
|
||||||
|
color: {r: 0.14901961, g: 0.15686275, b: 0.2509804, a: 1}
|
||||||
|
- id: panel_light
|
||||||
|
color: {r: 1, g: 1, b: 1, a: 0.101960786}
|
||||||
|
- id: panel_shadow
|
||||||
|
color: {r: 0.078431375, g: 0.07058824, b: 0.101960786, a: 0.34901962}
|
||||||
|
- id: panel_pattern
|
||||||
|
color: {r: 1, g: 1, b: 1, a: 0.050980393}
|
||||||
|
- id: panel_ground
|
||||||
|
color: {r: 0, g: 0, b: 0, a: 0.18039216}
|
||||||
|
- id: band_title
|
||||||
|
color: {r: 0.07058824, g: 0.101960786, b: 0.2, a: 1}
|
||||||
|
- id: row_band
|
||||||
|
color: {r: 1, g: 1, b: 1, a: 0.05882353}
|
||||||
|
- id: divider
|
||||||
|
color: {r: 1, g: 1, b: 1, a: 0.2509804}
|
||||||
|
- id: seat_plate
|
||||||
|
color: {r: 0.101960786, g: 0.10980392, b: 0.18039216, a: 0.9019608}
|
||||||
|
- id: seat_light
|
||||||
|
color: {r: 1, g: 1, b: 1, a: 0.078431375}
|
||||||
|
- id: seat_dim
|
||||||
|
color: {r: 0, g: 0, b: 0, a: 0.34901962}
|
||||||
skins:
|
skins:
|
||||||
- id: card
|
- id: card
|
||||||
pack: {fileID: 21300000, guid: 3070a6f23e6ca4273897acf1b7e8c5ce, type: 3}
|
pack: {fileID: 21300000, guid: 3070a6f23e6ca4273897acf1b7e8c5ce, type: 3}
|
||||||
|
|
@ -1035,6 +1059,90 @@ MonoBehaviour:
|
||||||
ppu: 1
|
ppu: 1
|
||||||
inset: {x: 6, y: 4, z: 6, w: 34}
|
inset: {x: 6, y: 4, z: 6, w: 34}
|
||||||
overlayAlpha: 0.2
|
overlayAlpha: 0.2
|
||||||
|
- id: panel_frame
|
||||||
|
pack: {fileID: 21300000, guid: 3070a6f23e6ca4273897acf1b7e8c5ce, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 0}
|
||||||
|
ppu: 1
|
||||||
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
overlayAlpha: 1
|
||||||
|
- id: panel_field
|
||||||
|
pack: {fileID: 21300000, guid: 6c9211bc1d90b4e35a3a080121e93d05, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 0}
|
||||||
|
ppu: 1
|
||||||
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
overlayAlpha: 1
|
||||||
|
- id: panel_light
|
||||||
|
pack: {fileID: 21300000, guid: d332162b7f97a44c8968e3570e42e325, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 0}
|
||||||
|
ppu: 1
|
||||||
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
overlayAlpha: 1
|
||||||
|
- id: band_title
|
||||||
|
pack: {fileID: 21300000, guid: f902adce59d3b4e8f993d11ba251e7d2, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 0}
|
||||||
|
ppu: 1
|
||||||
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
overlayAlpha: 1
|
||||||
|
- id: row_band
|
||||||
|
pack: {fileID: 21300000, guid: ae11cdefb6cd4436393f83b724ceb984, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 0}
|
||||||
|
ppu: 0.625
|
||||||
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
overlayAlpha: 1
|
||||||
|
- id: divider
|
||||||
|
pack: {fileID: 21300000, guid: 0c18e637bc71d4fc887d62f484000575, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 0}
|
||||||
|
ppu: 1
|
||||||
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
overlayAlpha: 1
|
||||||
|
- id: seat_plate
|
||||||
|
pack: {fileID: 21300000, guid: ae11cdefb6cd4436393f83b724ceb984, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 0}
|
||||||
|
ppu: 0.625
|
||||||
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
overlayAlpha: 1
|
||||||
|
- id: focus_line
|
||||||
|
pack: {fileID: 21300000, guid: d3ed2cc3ba43a449ca414493c0c2b8ae, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 0}
|
||||||
|
ppu: 1
|
||||||
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
overlayAlpha: 1
|
||||||
|
- id: badge_circle
|
||||||
|
pack: {fileID: 21300000, guid: fe62dbba2502e4766a8150113c51bef0, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 0}
|
||||||
|
ppu: 1
|
||||||
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
overlayAlpha: 1
|
||||||
|
- id: check_circle
|
||||||
|
pack: {fileID: 21300000, guid: 5a25a392cf93544beb9c3d76420b92ef, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 0}
|
||||||
|
ppu: 1
|
||||||
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
overlayAlpha: 1
|
||||||
|
- id: scroll_fade
|
||||||
|
pack: {fileID: 21300000, guid: c75fde6c7cc1847fcbe1fac91002ce1f, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 0}
|
||||||
|
ppu: 1
|
||||||
|
inset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
overlayAlpha: 1
|
||||||
|
- id: btn_s_green
|
||||||
|
pack: {fileID: 21300000, guid: 2d734a17e89824d30b1f014a9c1f5f60, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
overlay: {fileID: 21300000, guid: 1047c0bcbda25440faf8332b872b3529, type: 3}
|
||||||
|
ppu: 1.8
|
||||||
|
inset: {x: 4, y: 3, z: 4, w: 10}
|
||||||
|
overlayAlpha: 0.35
|
||||||
icons:
|
icons:
|
||||||
- id: cur_gold
|
- id: cur_gold
|
||||||
pack: {fileID: 21300000, guid: 6d5687fb0dd3a428d9cd26a6f36c6d78, type: 3}
|
pack: {fileID: 21300000, guid: 6d5687fb0dd3a428d9cd26a6f36c6d78, type: 3}
|
||||||
|
|
@ -1336,6 +1444,14 @@ MonoBehaviour:
|
||||||
pack: {fileID: 21300000, guid: 30dce27e256a74aa797da5e70d1c9a08, type: 3}
|
pack: {fileID: 21300000, guid: 30dce27e256a74aa797da5e70d1c9a08, type: 3}
|
||||||
samguk: {fileID: 0}
|
samguk: {fileID: 0}
|
||||||
tint: {r: 1, g: 1, b: 1, a: 1}
|
tint: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
- id: plus_glyph
|
||||||
|
pack: {fileID: 21300000, guid: a707b1e1252f042c58519d2882ee2651, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
tint: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
- id: check_badge
|
||||||
|
pack: {fileID: 21300000, guid: 5368592eacfda44c191265e7475562df, type: 3}
|
||||||
|
samguk: {fileID: 0}
|
||||||
|
tint: {r: 1, g: 1, b: 1, a: 1}
|
||||||
- id: tile_bridge
|
- id: tile_bridge
|
||||||
pack: {fileID: 0}
|
pack: {fileID: 0}
|
||||||
samguk: {fileID: 21300000, guid: 8e5bf7eb1e300474785ff2781eeb5093, type: 3}
|
samguk: {fileID: 21300000, guid: 8e5bf7eb1e300474785ff2781eeb5093, type: 3}
|
||||||
|
|
|
||||||
|
|
@ -39,14 +39,29 @@ namespace TKS.OutGame
|
||||||
get { return dirty; }
|
get { return dirty; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// 자리 카드 = 영웅 목록 카드(320×431) × SeatScale · 보유 목록 카드 × ListScale(PD 2026-11-09 「변경된 영웅 리스트 반영 · 편성 유닛 정보를 목록·상세 UI 참고해 깔끔하게」)
|
// Fable 제안서 §3(2026-11-09 · PD 「편성 메뉴와 영웅 목록 프레임 구분 · 디자인 요소 · 카드 목록 완성도」) — 본문 좌표 = 절대 y − 224
|
||||||
const float SeatScale = 0.70f;
|
// 섹션 A 「출전 편성」 패널(절대 236~1010) · 홈 16 · 섹션 B 「보유 영웅」 패널(1026~1760) · 자리 = 목록 카드 × SeatScale · 보유 = × ListScale
|
||||||
|
const float SeatScale = 0.62f;
|
||||||
const float ListScale = 0.72f;
|
const float ListScale = 0.72f;
|
||||||
const float SeatGap = 24f;
|
const float SeatPitch = 222f; // 자리 중심 간격(198 + 24)
|
||||||
const float BoardTop = 122f;
|
const float SeatCenterX = 608f; // 자리 줄 가운데(절대 x · 왼쪽 라벨 칸만큼 오른쪽)
|
||||||
const float BoardH = 680f;
|
const float PanelX = 24f, PanelW = 1032f;
|
||||||
|
const float PanelA_Y = 12f, PanelA_H = 774f; // 절대 236~1010
|
||||||
|
const float PanelB_Y = 802f, PanelB_H = 734f; // 절대 1026~1760
|
||||||
|
const float FrontY = 180f, BackY = 483f; // 자리 위 끝(패널 A 기준 · 절대 416 / 719)
|
||||||
Text countText;
|
Text countText;
|
||||||
Text filterText;
|
Text filterText;
|
||||||
|
Text ownedCount;
|
||||||
|
Text powerText;
|
||||||
|
Image saveImg;
|
||||||
|
Text saveText;
|
||||||
|
Image saveDot;
|
||||||
|
readonly List<GameObject> presetTails = new List<GameObject>();
|
||||||
|
|
||||||
|
static RectTransform At(Transform p, string name, float x, float y, float w, float h)
|
||||||
|
{
|
||||||
|
return UiKit.Rect(name, p, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(x, -y), new Vector2(w, h));
|
||||||
|
}
|
||||||
|
|
||||||
public override void Build()
|
public override void Build()
|
||||||
{
|
{
|
||||||
|
|
@ -55,37 +70,68 @@ namespace TKS.OutGame
|
||||||
// 바탕 = 영웅 목록과 같음(진남 + 재화 바 뒤 띠) · 헤더 오른쪽 사선 칸 = 출전 n / 칸 수
|
// 바탕 = 영웅 목록과 같음(진남 + 재화 바 뒤 띠) · 헤더 오른쪽 사선 칸 = 출전 n / 칸 수
|
||||||
UiKit.Paint(UiKit.Fill("ListBg", Rt), UiKit.Col("list_bg", UiKit.Bg), false);
|
UiKit.Paint(UiKit.Fill("ListBg", Rt), UiKit.Col("list_bg", UiKit.Bg), false);
|
||||||
UiKit.Paint(UiKit.TopBand("ListTop", Rt, 0f, OutGameRoot.TopBarH), UiKit.Col("band_top", UiKit.Bg), false);
|
UiKit.Paint(UiKit.TopBand("ListTop", Rt, 0f, OutGameRoot.TopBarH), UiKit.Col("band_top", UiKit.Bg), false);
|
||||||
var head = Header("편성", "", true); // 부제 삭제(설계서 §2-5)
|
var head = Header("편성", "", true);
|
||||||
var ob = UiKit.Rect("Oblique", head, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), Vector2.zero, new Vector2(239f, OutGameRoot.HeaderH - 7f));
|
var ob = UiKit.Rect("Oblique", head, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), Vector2.zero, new Vector2(239f, OutGameRoot.HeaderH - 7f));
|
||||||
UiKit.Skin(ob, "oblique", UiKit.Col("oblique", UiKit.White));
|
UiKit.Skin(ob, "oblique", UiKit.Col("oblique", UiKit.White));
|
||||||
countText = UiKit.Title(UiKit.Label(ob, "", 40, UiKit.Col("count_text", UiKit.Dark), TextAnchor.MiddleCenter, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(12f, 0f), new Vector2(220f, 80f)));
|
countText = UiKit.Title(UiKit.Label(ob, "", 40, UiKit.Col("count_text", UiKit.Dark), TextAnchor.MiddleCenter, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(12f, 0f), new Vector2(220f, 80f)));
|
||||||
countText.horizontalOverflow = HorizontalWrapMode.Overflow;
|
countText.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
var body = Body();
|
// 본문 = 1080 폭 틀(낮은 화면에서도 가운데)
|
||||||
|
var body = UiKit.Rect("Mock", Body(), new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), Vector2.zero, new Vector2(OutGameRoot.Reference.x, OutGameRoot.BodyH));
|
||||||
|
|
||||||
// 프리셋 3(팩 서브탭) + 제약 칩
|
// ===== 섹션 A 「출전 편성」 =====
|
||||||
|
RectTransform a;
|
||||||
|
UiKit.SectionPanel(body, "PanelA", PanelX, PanelA_Y, PanelW, PanelA_H, true, true, out a);
|
||||||
|
UiKit.SectionTitle(a, "출전 편성");
|
||||||
|
// 제약 칩(ⓘ = 편성 안내 팝업 · 안내 문장 이관)
|
||||||
|
var lim = At(a, "Limit", 592f, 8f, 230f, 56f);
|
||||||
|
UiKit.Skin(lim, "chip", UiKit.Col("chip_dark", UiKit.Dark), true);
|
||||||
|
UiKit.Layer(lim, "Line", "chip_line", UiKit.Col("chip_line", Color.clear), 4f, 4f, 4f, 4f);
|
||||||
|
UiKit.Label(lim, "편성 제약 없음", 26, UiKit.Col("text_soft", UiKit.InkSoft), TextAnchor.MiddleLeft, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(18f, 0f), new Vector2(170f, 50f)).horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
UiKit.Icon(lim, "info", new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-16f, 0f), 32f);
|
||||||
|
lim.gameObject.AddComponent<Button>().onClick.AddListener(ShowGuide);
|
||||||
|
// 저장(녹 · 바뀐 것 없으면 비활성 색 · 바뀌면 알림 점)
|
||||||
|
var sv = At(a, "Save", 832f, 4f, 180f, 68f);
|
||||||
|
saveImg = UiKit.Skin(sv, UISkin.Has("btn_s_green") ? "btn_s_green" : "button", UiKit.White, true);
|
||||||
|
sv.gameObject.AddComponent<Button>().onClick.AddListener(SaveNow);
|
||||||
|
saveText = UiKit.Title(UiKit.Label(sv, "저장", 34, UiKit.Col("text_on_green", UiKit.Dark), TextAnchor.MiddleCenter, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 5f), new Vector2(170f, 56f)));
|
||||||
|
saveDot = UiKit.Icon(sv, "new_dot", new Vector2(1f, 1f), new Vector2(0.5f, 0.5f), new Vector2(-8f, -8f), 26f);
|
||||||
|
// 프리셋 탭 3 + 출전 꼬리 칩
|
||||||
for (int i = 0; i < S.Save.presets.Count; i++)
|
for (int i = 0; i < S.Save.presets.Count; i++)
|
||||||
{
|
{
|
||||||
int k = i;
|
int k = i;
|
||||||
presetBtns.Add(SubTab("Preset" + i, body, "프리셋 " + (i + 1), new Vector2(24f + i * 226f, -18f), new Vector2(210f, 84f), () => LoadPreset(k)));
|
var b = SubTab("Preset" + i, a, "프리셋 " + (i + 1), new Vector2(20f + i * 212f, -84f), new Vector2(200f, 72f), () => LoadPreset(k));
|
||||||
|
presetBtns.Add(b);
|
||||||
|
var tail = UiKit.Skin(UiKit.Rect("Active", b.transform, new Vector2(1f, 1f), new Vector2(1f, 0.5f), new Vector2(6f, -2f), new Vector2(72f, 34f)), "tail", UiKit.Col("tail_red", UiKit.Red));
|
||||||
|
UiKit.Title(UiKit.FillLabel(tail.transform, "출전", 20, UiKit.White), true);
|
||||||
|
presetTails.Add(tail.gameObject);
|
||||||
}
|
}
|
||||||
var chip = UiKit.Skin(UiKit.Rect("Free", body, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-24f, -24f), new Vector2(270f, 72f)), "chip", UiKit.Col("chip_dark", UiKit.Dark));
|
// 총 전투력 칩(편성 변화가 숫자로 바로 보임)
|
||||||
UiKit.Title(UiKit.FillLabel(chip.transform, "편성 제약 없음", 30, UiKit.White), false);
|
var pw = At(a, "Power", 736f, 88f, 276f, 64f);
|
||||||
|
UiKit.Skin(pw, "chip", UiKit.Col("chip_dark", UiKit.Dark));
|
||||||
// 자리 판 = 전열(윗줄) · 후열(아랫줄) · 자리 = 목록과 같은 카드
|
UiKit.Icon(pw, "sword", new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(12f, 0f), 44f);
|
||||||
|
UiKit.Label(pw, "전투력", 24, UiKit.Col("text_soft", UiKit.InkSoft), TextAnchor.MiddleLeft, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(62f, 0f), new Vector2(90f, 40f));
|
||||||
|
powerText = UiKit.Title(UiKit.Label(pw, "", 40, UiKit.White, TextAnchor.MiddleRight, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-18f, 2f), new Vector2(150f, 56f)), true);
|
||||||
|
powerText.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
// 열 밴드 2 · 구분선 · 전열/후열 칩
|
||||||
|
UiKit.Skin(At(a, "FrontBand", 20f, 172f, 992f, 283f), "row_band", UiKit.Col("row_band", Color.clear));
|
||||||
|
UiKit.Skin(At(a, "Divider", 76f, 461f, 880f, 8f), "divider", UiKit.Col("divider", Color.clear));
|
||||||
|
UiKit.Skin(At(a, "BackBand", 20f, 475f, 992f, 283f), "row_band", UiKit.Col("row_band", Color.clear));
|
||||||
|
Pill(a, "전열", UiKit.Col("row_front", UiKit.Red), 20f, 286f);
|
||||||
|
Pill(a, "후열", UiKit.Col("row_back", UiKit.Dark), 20f, 589f);
|
||||||
|
// 자리 = 받침(빈 자리에도) + 카드 칸
|
||||||
float sw = CollectionCards.CellSize.x * SeatScale, sh = CollectionCards.CellSize.y * SeatScale;
|
float sw = CollectionCards.CellSize.x * SeatScale, sh = CollectionCards.CellSize.y * SeatScale;
|
||||||
var board = UiKit.TopBand("Board", body, BoardTop, BoardH, 24f, 24f);
|
|
||||||
UiKit.Skin(board, "card", UiKit.Col("formation_field", UiKit.Paper));
|
|
||||||
Pill(board, "전열", UiKit.Col("row_front", UiKit.Red), -(20f + sh / 2f));
|
|
||||||
Pill(board, "후열", UiKit.Col("row_back", UiKit.Dark), -(20f + sh + 20f + sh / 2f));
|
|
||||||
UiKit.Label(board, "탭·드래그 = 자리 교체 · 같은 자리 두 번 탭 = 빼기", 24, UiKit.InkSoft, TextAnchor.MiddleLeft, new Vector2(0f, 0f), new Vector2(0f, 0f), new Vector2(24f, 2f), new Vector2(900f, 34f), false);
|
|
||||||
for (int i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
bool f = i < front;
|
bool f = i < front;
|
||||||
int col = f ? i : i - front;
|
int col = f ? i : i - front;
|
||||||
int cnt = f ? front : n - front;
|
int cnt = f ? front : n - front;
|
||||||
float x = 60f + (col - (cnt - 1) / 2f) * (sw + SeatGap);
|
float cx = SeatCenterX - PanelX + (col - (cnt - 1) / 2f) * SeatPitch;
|
||||||
float y = f ? -20f : -(20f + sh + 20f);
|
float top = f ? FrontY : BackY;
|
||||||
var s = UiKit.Rect("Slot" + i, board, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(x, y), new Vector2(sw, sh));
|
var plate = At(a, "Plate" + i, cx - sw / 2f - 8f, top - 8f, sw + 16f, sh + 16f);
|
||||||
|
UiKit.Skin(plate, "seat_plate", UiKit.Col("seat_plate", UiKit.Dark));
|
||||||
|
var pl = UiKit.Rect("Light", plate, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -4f), new Vector2(sw, 10f));
|
||||||
|
UiKit.Skin(pl, "panel_light", UiKit.Col("seat_light", Color.clear)).enabled = UISkin.Has("panel_light");
|
||||||
|
var s = At(a, "Slot" + i, cx - sw / 2f, top, sw, sh);
|
||||||
var hit = s.gameObject.AddComponent<Image>();
|
var hit = s.gameObject.AddComponent<Image>();
|
||||||
hit.color = Color.clear;
|
hit.color = Color.clear;
|
||||||
hit.raycastTarget = true;
|
hit.raycastTarget = true;
|
||||||
|
|
@ -99,22 +145,35 @@ namespace TKS.OutGame
|
||||||
slots.Add(s);
|
slots.Add(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 보유 목록 머리 = 제목 · 「장수 ▼」(영웅 목록과 같은 전환) · 저장
|
// ===== 섹션 B 「보유 영웅」 =====
|
||||||
var row = UiKit.TopBand("ListHead", body, BoardTop + BoardH + 16f, 74f, 24f, 24f);
|
RectTransform b2;
|
||||||
UiKit.Title(UiKit.Label(row, "보유 영웅", 40, UiKit.White, TextAnchor.MiddleLeft, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(4f, 0f), new Vector2(300f, 70f)), true);
|
UiKit.SectionPanel(body, "PanelB", PanelX, PanelB_Y, PanelW, PanelB_H, false, false, out b2);
|
||||||
var pick = UiKit.Rect("Filter", row, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-244f, 0f), new Vector2(220f, 74f));
|
var tb = UiKit.SectionTitle(b2, "보유 영웅");
|
||||||
pick.gameObject.AddComponent<Image>().color = Color.clear;
|
var cnt2 = UiKit.Skin(UiKit.Rect("Count", tb, new Vector2(0f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(300f, 2f), new Vector2(44f, 46f)), "badge_circle", UiKit.Col("grade_blue", UiKit.Dark));
|
||||||
|
cnt2.preserveAspect = true;
|
||||||
|
ownedCount = UiKit.Title(UiKit.FillLabel(cnt2.transform, "", 26, UiKit.White), true);
|
||||||
|
// 「장수 ▼」 필터 칩
|
||||||
|
var pick = At(b2, "Filter", 812f, 6f, 200f, 56f);
|
||||||
|
UiKit.Skin(pick, "chip", UiKit.Col("chip_dark", UiKit.Dark), true);
|
||||||
|
UiKit.Layer(pick, "Line", "chip_line", UiKit.Col("chip_line", Color.clear), 4f, 4f, 4f, 4f);
|
||||||
pick.gameObject.AddComponent<Button>().onClick.AddListener(() =>
|
pick.gameObject.AddComponent<Button>().onClick.AddListener(() =>
|
||||||
{
|
{
|
||||||
soldiers = !soldiers;
|
soldiers = !soldiers;
|
||||||
Refresh();
|
Refresh();
|
||||||
});
|
});
|
||||||
filterText = UiKit.Title(UiKit.Label(pick, "", 38, UiKit.InkSoft, TextAnchor.MiddleRight, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-50f, 2f), new Vector2(160f, 70f)));
|
filterText = UiKit.Title(UiKit.Label(pick, "", 30, UiKit.White, TextAnchor.MiddleCenter, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(-18f, 2f), new Vector2(140f, 50f)));
|
||||||
UiKit.DropShadow(UiKit.Icon(pick, "arrow_down", new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-6f, 0f), 38f), 3f);
|
UiKit.Icon(pick, "arrow_down", new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-22f, 0f), 28f);
|
||||||
UiKit.Btn("Save", row, "저장", 34, UiKit.Red, UiKit.White, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), Vector2.zero, new Vector2(210f, 76f), SaveNow);
|
// 격자 4열(절대 x 54~1026 · y 1108~1748) + 위·아래 페이드
|
||||||
var cell = CollectionCards.CellSize * ListScale;
|
var cell = CollectionCards.CellSize * ListScale;
|
||||||
float side = (OutGameRoot.Reference.x - cell.x * 4f - 17f * 3f) / 2f;
|
float gridTop = 1108f - 224f, gridBottom = OutGameRoot.BodyH - (1748f - 224f);
|
||||||
list = UiKit.ScrollGrid("List", body, side, side, BoardTop + BoardH + 100f, 0f, cell, new Vector2(17f, 16f), 4, out scroll);
|
list = UiKit.ScrollGrid("List", body, 54f, 54f, gridTop, gridBottom, cell, new Vector2(17f, 16f), 4, out scroll);
|
||||||
|
UiKit.ScrollFades(body, gridTop, gridBottom, 40f, 30f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>편성 안내(제약 칩 ⓘ · 화면의 안내 문장을 이관).</summary>
|
||||||
|
void ShowGuide()
|
||||||
|
{
|
||||||
|
Root.Modal("편성 안내", "편성 제약 없음 · 빈 칸 허용 · 최소 1명\n\n자리 탭 → 카드 탭 = 넣기 · 교체\n같은 자리 두 번 탭 = 빼기\n끌기 = 자리 ↔ 자리 · 카드 → 자리\n저장 = 이 프리셋을 출전 편성으로", new OutGameRoot.ModalButton("확인", UiKit.Dark, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>서브탭(팩 Button_Round10 + 윗면 광택 · 선택 = 붉은 옻칠).</summary>
|
/// <summary>서브탭(팩 Button_Round10 + 윗면 광택 · 선택 = 붉은 옻칠).</summary>
|
||||||
|
|
@ -123,17 +182,17 @@ namespace TKS.OutGame
|
||||||
var img = UiKit.Skin(UiKit.Rect(name, parent, new Vector2(0f, 1f), new Vector2(0f, 1f), pos, size), UISkin.Has("subtab") ? "subtab" : "button", UiKit.Col("subtab_off", UiKit.Paper), true);
|
var img = UiKit.Skin(UiKit.Rect(name, parent, new Vector2(0f, 1f), new Vector2(0f, 1f), pos, size), UISkin.Has("subtab") ? "subtab" : "button", UiKit.Col("subtab_off", UiKit.Paper), true);
|
||||||
var b = img.gameObject.AddComponent<Button>();
|
var b = img.gameObject.AddComponent<Button>();
|
||||||
b.onClick.AddListener(() => onClick());
|
b.onClick.AddListener(() => onClick());
|
||||||
UiKit.Title(UiKit.FillLabel(img.transform, label, 34, UiKit.White, TextAnchor.MiddleCenter, true, 8f), true);
|
UiKit.Title(UiKit.FillLabel(img.transform, label, 32, UiKit.White, TextAnchor.MiddleCenter, true, 8f), true);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Pill(RectTransform board, string label, Color c, float y)
|
static void Pill(RectTransform panel, string label, Color c, float x, float y)
|
||||||
{
|
{
|
||||||
// 전열·후열 라벨 = 평행사변형 칩(설계서 §3③)
|
// 전열·후열 라벨 = 평행사변형 칩 120×54(Fable §3-3)
|
||||||
var p = UISkin.Has("para_orange")
|
var p = UISkin.Has("para_orange")
|
||||||
? UiKit.Skin(UiKit.Rect("Row_" + label, board, new Vector2(0f, 1f), new Vector2(0f, 0.5f), new Vector2(20f, y), new Vector2(140f, 62f)), "para_orange", c)
|
? UiKit.Skin(At(panel, "Row_" + label, x, y, 120f, 54f), "para_orange", c)
|
||||||
: UiKit.Box("Row_" + label, board, new Vector2(0f, 1f), new Vector2(0f, 0.5f), new Vector2(20f, y), new Vector2(140f, 62f), c);
|
: UiKit.Paint(At(panel, "Row_" + label, x, y, 120f, 54f), c);
|
||||||
UiKit.Title(UiKit.FillLabel(p.transform, label, 32, UiKit.White), true);
|
UiKit.Title(UiKit.FillLabel(p.transform, label, 28, UiKit.White), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnShow()
|
public override void OnShow()
|
||||||
|
|
@ -316,30 +375,46 @@ namespace TKS.OutGame
|
||||||
presetBtns[i].GetComponent<Image>().color = on ? UiKit.Red : UiKit.Col("subtab_off", UiKit.Paper);
|
presetBtns[i].GetComponent<Image>().color = on ? UiKit.Red : UiKit.Col("subtab_off", UiKit.Paper);
|
||||||
var t = UiKit.LabelOf(presetBtns[i]);
|
var t = UiKit.LabelOf(presetBtns[i]);
|
||||||
t.color = UiKit.White;
|
t.color = UiKit.White;
|
||||||
t.text = "프리셋 " + (i + 1) + (i == S.Save.presetIdx ? " <size=22>출전</size>" : "") + (on && dirty ? "*" : "");
|
t.text = "프리셋 " + (i + 1) + (on && dirty ? "*" : "");
|
||||||
|
presetTails[i].SetActive(i == S.Save.presetIdx);
|
||||||
}
|
}
|
||||||
countText.text = "출전 " + Filled() + "/" + work.Count;
|
countText.text = "출전 " + Filled() + "/" + work.Count;
|
||||||
|
float power = 0f;
|
||||||
|
foreach (var id in work)
|
||||||
|
if (!string.IsNullOrEmpty(id) && S.Def(id) != null) power += S.StatsOf(id).power;
|
||||||
|
powerText.text = power.ToString("N0");
|
||||||
|
// 저장 = 바뀐 것이 있을 때만 녹(+ 알림 점)
|
||||||
|
saveImg.color = dirty ? UiKit.White : UiKit.Col("disabled", UiKit.Dark);
|
||||||
|
saveText.color = UiKit.Col(dirty ? "text_on_green" : "disabled_text", UiKit.Dark);
|
||||||
|
if (saveDot != null) saveDot.gameObject.SetActive(dirty);
|
||||||
|
|
||||||
// 자리 = 목록과 같은 카드(배율) · 빈 자리 = 빈 카드 · 고른 자리 = 노란 테두리
|
// 자리 = 목록 카드(배율) · 빈 자리 = 원본 빈 카드 + 초록 플러스 뱃지 · 고른 자리 = 노란 포커스 테두리(깜빡)
|
||||||
for (int i = 0; i < slots.Count; i++)
|
for (int i = 0; i < slots.Count; i++)
|
||||||
{
|
{
|
||||||
var s = slots[i];
|
var s = slots[i];
|
||||||
UiKit.Clear(s);
|
UiKit.Clear(s);
|
||||||
var id = i < work.Count ? work[i] : "";
|
var id = i < work.Count ? work[i] : "";
|
||||||
var h = S.Def(id);
|
var h = S.Def(id);
|
||||||
if (i == selected) UiKit.Layer(s, "Select", "card_border", UiKit.Col("select_line", UiKit.Star), -7f, -7f, -7f, -7f);
|
|
||||||
if (h != null) CollectionCards.CardIn(s, S, h, false, null, SeatScale);
|
if (h != null) CollectionCards.CardIn(s, S, h, false, null, SeatScale);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CollectionCards.EmptyIn(s, SeatScale);
|
CollectionCards.EmptyIn(s, SeatScale);
|
||||||
UiKit.Title(UiKit.Label(s, "+ 빈 자리", 28, UiKit.InkSoft, TextAnchor.MiddleCenter, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 24f), new Vector2(200f, 50f)));
|
var badge = UiKit.Skin(UiKit.Rect("Plus", s, new Vector2(1f, 0f), new Vector2(0.5f, 0.5f), new Vector2(-24f, 24f), new Vector2(48f, 50f)), "badge_circle", UiKit.Col("ok", UiKit.Red));
|
||||||
|
badge.preserveAspect = true;
|
||||||
|
UiKit.Icon(badge.transform, "plus_glyph", new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 1f), 26f);
|
||||||
|
}
|
||||||
|
if (i == selected)
|
||||||
|
{
|
||||||
|
var fx = UiKit.Layer(s, "Select", "focus_line", UiKit.Col("select_line", UiKit.Star), -6f, -6f, -6f, -6f);
|
||||||
|
fx.gameObject.AddComponent<UiPulse>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 보유 목록 = 영웅 목록 카드(배율 · 레벨 높은 순 · 출전 = 이 편성에 든 영웅)
|
// 보유 목록 = 영웅 목록 카드(배율 · 레벨 높은 순) · 출전 중 = 꼬리 칩 + 35 % 덮개 + 초록 체크 뱃지
|
||||||
filterText.text = soldiers ? "병사" : "장수";
|
filterText.text = soldiers ? "병사" : "장수";
|
||||||
UiKit.Clear(list);
|
UiKit.Clear(list);
|
||||||
var owned = new List<HeroDb.Hero>(S.Owned(soldiers));
|
var owned = new List<HeroDb.Hero>(S.Owned(soldiers));
|
||||||
|
ownedCount.text = owned.Count.ToString();
|
||||||
owned.Sort((a, b) =>
|
owned.Sort((a, b) =>
|
||||||
{
|
{
|
||||||
int la = S.Save.Level(a.id) != null ? S.Save.Level(a.id).lv : 1, lb = S.Save.Level(b.id) != null ? S.Save.Level(b.id).lv : 1;
|
int la = S.Save.Level(a.id) != null ? S.Save.Level(a.id).lv : 1, lb = S.Save.Level(b.id) != null ? S.Save.Level(b.id).lv : 1;
|
||||||
|
|
@ -349,8 +424,17 @@ namespace TKS.OutGame
|
||||||
foreach (var h in owned)
|
foreach (var h in owned)
|
||||||
{
|
{
|
||||||
var id = h.id;
|
var id = h.id;
|
||||||
|
bool on = work.Contains(id);
|
||||||
var holder = UiKit.Rect("C_" + id, list, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, cellSize);
|
var holder = UiKit.Rect("C_" + id, list, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, cellSize);
|
||||||
var card = CollectionCards.CardIn(holder, S, h, work.Contains(id), null, ListScale);
|
var card = CollectionCards.CardIn(holder, S, h, on, null, ListScale);
|
||||||
|
if (on)
|
||||||
|
{
|
||||||
|
var dim = UiKit.Layer(card.transform, "Dim", "card_bg", UiKit.Col("seat_dim", Color.clear), 2f, 2f, 2f, 2f);
|
||||||
|
dim.transform.SetSiblingIndex(2); // 바탕·테두리 위 · 글자·뱃지 아래
|
||||||
|
var ck = UiKit.Skin(UiKit.Rect("Check", card.transform, new Vector2(1f, 0f), new Vector2(0.5f, 0.5f), new Vector2(-48f, 118f), new Vector2(72f, 75f)), "check_circle", UiKit.Col("ok", UiKit.Red));
|
||||||
|
ck.preserveAspect = true;
|
||||||
|
UiKit.Icon(ck.transform, "check_badge", new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 2f), 42f);
|
||||||
|
}
|
||||||
var td = card.gameObject.AddComponent<TapDrag>();
|
var td = card.gameObject.AddComponent<TapDrag>();
|
||||||
td.OnTap = () => TapCard(id);
|
td.OnTap = () => TapCard(id);
|
||||||
td.OnDragStart = e => StartGhost(id, e);
|
td.OnDragStart = e => StartGhost(id, e);
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,68 @@ namespace TKS.OutGame
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 섹션 패널(Fable 제안서 §3-2 · §5-1) = 그림자(아래 6) → 프레임(#3F4262) → 필드(안쪽 6 · #262840 · 마스크) [→ 문양 타일 5 %] [→ 바닥 그라데이션] → 윗면 광택 h14.
|
||||||
|
/// 위치 = 부모 왼쪽 위 기준(x, y 아래로) · 반환 = 필드(내용은 필드 자식 · 필드 모양으로 잘림 · 잘리면 안 되는 내용은 패널 루트에).
|
||||||
|
/// </summary>
|
||||||
|
public static RectTransform SectionPanel(Transform parent, string name, float x, float y, float w, float h, bool pattern, bool ground, out RectTransform root)
|
||||||
|
{
|
||||||
|
root = Rect(name, parent, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(x, -y), new Vector2(w, h));
|
||||||
|
Layer(root, "Shadow", "panel_frame", Col("panel_shadow", new Color(0f, 0f, 0f, 0.35f)), 0f, 6f, 0f, -6f);
|
||||||
|
Layer(root, "Frame", "panel_frame", Col("panel_frame", Paper));
|
||||||
|
var field = Layer(root, "Field", "panel_field", Col("panel_field", Dark), 6f, 6f, 6f, 6f);
|
||||||
|
field.gameObject.AddComponent<Mask>().showMaskGraphic = true;
|
||||||
|
if (pattern && UISkin.Has("bg_pattern"))
|
||||||
|
{
|
||||||
|
var pat = Layer(field.transform, "Pattern", "bg_pattern", Col("panel_pattern", Color.clear));
|
||||||
|
pat.type = Image.Type.Tiled;
|
||||||
|
}
|
||||||
|
if (ground && UISkin.Has("scroll_fade"))
|
||||||
|
{
|
||||||
|
// 스프라이트 = 위 불투명 → 아래 투명(실측) → 뒤집어 바닥이 어둡게
|
||||||
|
var g = Skin(Rect("Ground", field.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), Vector2.zero, new Vector2(0f, 120f)), "scroll_fade", Col("panel_ground", Color.clear));
|
||||||
|
g.rectTransform.anchorMin = new Vector2(0f, 0f);
|
||||||
|
g.rectTransform.anchorMax = new Vector2(1f, 0f);
|
||||||
|
g.rectTransform.sizeDelta = new Vector2(0f, 120f);
|
||||||
|
g.rectTransform.localScale = new Vector3(1f, -1f, 1f);
|
||||||
|
g.rectTransform.pivot = new Vector2(0.5f, 1f);
|
||||||
|
g.rectTransform.anchoredPosition = Vector2.zero;
|
||||||
|
}
|
||||||
|
var lrt = Rect("Light", root, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -8f), new Vector2(0f, 14f));
|
||||||
|
lrt.anchorMin = new Vector2(0f, 1f);
|
||||||
|
lrt.anchorMax = new Vector2(1f, 1f);
|
||||||
|
lrt.sizeDelta = new Vector2(-24f, 14f);
|
||||||
|
lrt.anchoredPosition = new Vector2(0f, -8f);
|
||||||
|
Skin(lrt, "panel_light", Col("panel_light", Color.clear)).enabled = UISkin.Has("panel_light");
|
||||||
|
return (RectTransform)field.transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>섹션 제목 띠(팩 Title_Tapered02 · 패널 왼쪽 위 모서리 · 360×69 · 글자 36 흰 외곽선 · 왼쪽 여백 36).</summary>
|
||||||
|
public static RectTransform SectionTitle(Transform panelRoot, string text, float w = 360f)
|
||||||
|
{
|
||||||
|
var band = Rect("Title", panelRoot, new Vector2(0f, 1f), new Vector2(0f, 1f), Vector2.zero, new Vector2(w, 69f));
|
||||||
|
if (UISkin.Has("band_title")) Skin(band, "band_title", Col("band_title", Dark));
|
||||||
|
var t = Title(Label(band, text, 36, White, TextAnchor.MiddleLeft, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(36f, 2f), new Vector2(w - 60f, 60f)), true);
|
||||||
|
t.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
return band;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>스크롤 위·아래 페이드(필드색 → 투명) — 목록이 패널 안에서 잘리는 느낌을 지움.</summary>
|
||||||
|
public static void ScrollFades(Transform parent, float top, float bottom, float h = 40f, float side = 12f)
|
||||||
|
{
|
||||||
|
if (!UISkin.Has("scroll_fade")) return;
|
||||||
|
var c = Col("panel_field", Dark);
|
||||||
|
var a = Skin(Rect("FadeTop", parent, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -top), new Vector2(0f, h)), "scroll_fade", c);
|
||||||
|
a.rectTransform.anchorMin = new Vector2(0f, 1f);
|
||||||
|
a.rectTransform.anchorMax = new Vector2(1f, 1f);
|
||||||
|
a.rectTransform.sizeDelta = new Vector2(-2f * side, h);
|
||||||
|
var b = Skin(Rect("FadeBottom", parent, new Vector2(0.5f, 0f), new Vector2(0.5f, 1f), new Vector2(0f, bottom), new Vector2(0f, h)), "scroll_fade", c);
|
||||||
|
b.rectTransform.anchorMin = new Vector2(0f, 0f);
|
||||||
|
b.rectTransform.anchorMax = new Vector2(1f, 0f);
|
||||||
|
b.rectTransform.sizeDelta = new Vector2(-2f * side, h);
|
||||||
|
b.rectTransform.localScale = new Vector3(1f, -1f, 1f);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>아이템 칸 5층(팩 ItemFrame00~03 · 색 = prefix + bg · deco · light · glow · 테두리 gear_border) — 장비·보물·보상 칸 공용.</summary>
|
/// <summary>아이템 칸 5층(팩 ItemFrame00~03 · 색 = prefix + bg · deco · light · glow · 테두리 gear_border) — 장비·보물·보상 칸 공용.</summary>
|
||||||
public static void ItemSlot(Transform cell, string prefix, bool lit)
|
public static void ItemSlot(Transform cell, string prefix, bool lit)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace TKS.OutGame
|
||||||
|
{
|
||||||
|
/// <summary>그래픽 알파 핑퐁(선택 테두리 등 · Fable 제안서 §3-3 「α 0.6↔1.0 0.8 s」) — 시간 = 실시간(일시정지 무관).</summary>
|
||||||
|
public class UiPulse : MonoBehaviour
|
||||||
|
{
|
||||||
|
public float min = 0.6f;
|
||||||
|
public float max = 1f;
|
||||||
|
public float period = 0.8f;
|
||||||
|
Graphic g;
|
||||||
|
float baseA = 1f;
|
||||||
|
|
||||||
|
void Awake()
|
||||||
|
{
|
||||||
|
g = GetComponent<Graphic>();
|
||||||
|
if (g != null) baseA = g.color.a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
if (g == null || period <= 0f) return;
|
||||||
|
float t = Mathf.PingPong(Time.unscaledTime / period, 1f);
|
||||||
|
var c = g.color;
|
||||||
|
c.a = baseA * Mathf.Lerp(min, max, t);
|
||||||
|
g.color = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 538d7515412d55042a8dd9b21c1ccd83
|
||||||
Loading…
Reference in New Issue