Update result boarding pass UI

This commit is contained in:
jongjae0305
2026-07-08 15:57:10 +09:00
parent a708f18499
commit 445d74d462
6 changed files with 311 additions and 35 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

@@ -0,0 +1,143 @@
fileFormatVersion: 2
guid: 314ce152a0f57814abb1f5a6f8510a13
TextureImporter:
internalIDToNameTable: []
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: 0
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 80
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: 1
swizzle: 50462976
cookieLightType: 1
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- 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: 1
- serializedVersion: 4
buildTarget: iOS
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- 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: 1
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 765d7d0805a5427a9b194266745a2daf
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
+113 -31
View File
@@ -41,7 +41,8 @@ public class GameFlowManager : MonoBehaviour {
private const string DutyFreeShopSceneName = "DutyFreeShop";
private const string MapPreviewSceneName = "MapPreview";
private const string DepartureStampResourcePath = "UI_DepartureStamp_Red";
private const string ResultPassportPanelResourcePath = "UI_LeftHudPassportHorizontalGridPanel";
private const string ResultPassportPanelResourcePath = "UI_ResultBoardingPassPanel_New";
private const string ResultPassportPanelAssetPath = "Assets/Resources/UI_ResultBoardingPassPanel_New.png";
private const string ResultAirportBackgroundResourcePath = "Map_Tutorial_Incheon_Airport";
private const string ResultButtonResourcePath = "UI_TutorialNextButton";
private const string ResultButtonAssetPath = "Assets/Resources/UI_TutorialNextButton.png";
@@ -494,7 +495,7 @@ public class GameFlowManager : MonoBehaviour {
panelRect.sizeDelta = new Vector2(1092f, 330f);
Image panelImage = panelObject.GetComponent<Image>();
panelImage.sprite = LoadUiSprite(ResultPassportPanelResourcePath, "Assets/Resources/UI_LeftHudPassportHorizontalGridPanel.png");
panelImage.sprite = LoadUiSprite(ResultPassportPanelResourcePath, ResultPassportPanelAssetPath);
panelImage.color = panelImage.sprite != null
? Color.white
: new Color(0.95f, 0.91f, 0.80f, 0.98f);
@@ -506,39 +507,45 @@ public class GameFlowManager : MonoBehaviour {
private void AddResultHeader(RectTransform parent, MapDefinition resultMap) {
Sprite rankSprite = LoadUiSprite("", ClearRankIconAssetPath);
Sprite stampSprite = LoadUiSprite(DepartureStampResourcePath, "Assets/Resources/UI_DepartureStamp_Red.png");
AddResultImage(parent, "Result Rank Badge", rankSprite, new Vector2(170f, -106f), new Vector2(50f, 50f), true, Color.white);
AddResultImage(parent, "Result Rank Badge", rankSprite, new Vector2(150f, -140f), new Vector2(48f, 48f), true, Color.white);
string title = lastResultCleared ? "출국 성공!" : "일정 실패";
Color titleColor = lastResultCleared
? new Color(0.05f, 0.17f, 0.27f, 1f)
: new Color(0.52f, 0.08f, 0.07f, 1f);
AddResultText(parent, "Result Title", title, new Vector2(194f, -88f), new Vector2(210f, 50f), 28f, FontStyles.Bold, titleColor, TextAlignmentOptions.MidlineLeft);
AddResultCenteredText(parent, "Result Title", title, new Vector2(244f, -140f), new Vector2(220f, 50f), 27f, FontStyles.Bold, titleColor, TextAlignmentOptions.Center);
string destination = GetResultDestinationName(resultMap);
AddResultText(parent, "Result Route", destination, new Vector2(260f, -140f), new Vector2(210f, 22f), 13f, FontStyles.Bold, new Color(0.25f, 0.42f, 0.50f, 0.96f), TextAlignmentOptions.MidlineLeft);
string routeText = GetResultOriginAirportCode(resultMap) + " -> " + GetResultDestinationAirportCode(resultMap);
AddResultCenteredText(parent, "Result Route Summary", routeText, new Vector2(244f, -181f), new Vector2(220f, 28f), 18f, FontStyles.Bold, new Color(0.17f, 0.34f, 0.43f, 0.98f), TextAlignmentOptions.Center);
AddResultCenteredText(parent, "Result Route Name", GetResultDestinationCityName(resultMap), new Vector2(244f, -207f), new Vector2(220f, 22f), 13f, FontStyles.Bold, new Color(0.43f, 0.58f, 0.64f, 0.96f), TextAlignmentOptions.Center);
if(lastResultCleared)
{
AddResultImage(parent, "Result Departure Stamp", stampSprite, new Vector2(250f, -232f), new Vector2(108f, 108f), true, new Color(1f, 1f, 1f, 0.92f));
TextMeshProUGUI stampText = AddResultText(parent, "Result Stamp Text", "출국\n성공", new Vector2(228f, -218f), new Vector2(92f, 48f), 21f, FontStyles.Bold, new Color(0.70f, 0.04f, 0.03f, 0.96f), TextAlignmentOptions.Center);
TextMeshProUGUI stampText = AddResultCenteredText(parent, "Result Stamp Text", "출국\n성공", new Vector2(238f, -260f), new Vector2(86f, 50f), 19f, FontStyles.Bold, new Color(0.70f, 0.04f, 0.03f, 0.96f), TextAlignmentOptions.Center);
stampText.lineSpacing = -16f;
}
else
{
AddResultText(parent, "Result Retry Note", "다시 준비해서\n출국 게이트까지", new Vector2(178f, -216f), new Vector2(200f, 56f), 17f, FontStyles.Bold, new Color(0.32f, 0.46f, 0.54f, 0.96f), TextAlignmentOptions.Center);
AddResultCenteredText(parent, "Result Retry Note", "다시 준비해서\n출국 게이트까지", new Vector2(244f, -260f), new Vector2(210f, 58f), 17f, FontStyles.Bold, new Color(0.32f, 0.46f, 0.54f, 0.96f), TextAlignmentOptions.Center);
}
AddResultRouteBox(parent, "From", GetResultOriginAirportCode(resultMap), GetResultOriginCityName(resultMap), new Vector2(440f, -122f));
AddResultRouteBox(parent, "To", GetResultDestinationAirportCode(resultMap), GetResultDestinationCityName(resultMap), new Vector2(657f, -122f));
AddResultBoardingField(parent, "Flight", "항공편", GetResultFlightName(resultMap), new Vector2(402f, -253f));
AddResultBoardingField(parent, "Seat", "좌석", GetResultSeatName(resultMap), new Vector2(512f, -253f));
AddResultBoardingField(parent, "Boarding", "탑승", System.DateTime.Now.ToString("HH:mm"), new Vector2(622f, -253f));
AddResultBoardingField(parent, "Class", "클래스", lastResultCleared ? "일반석" : "대기", new Vector2(732f, -253f));
}
private void AddResultStats(RectTransform parent, int gainedMileage, int shownDistance, int targetDistance) {
AddResultStat(parent, "Mileage", LoadUiSprite("", MileageIconAssetPath), "마일리지", "+" + gainedMileage, new Vector2(478f, -90f));
AddResultStat(parent, "Time", LoadUiSprite("", TimerIconAssetPath), "도착 시간", lastResultTime.ToString("0.0") + "s", new Vector2(626f, -90f));
AddResultStat(parent, "Mileage", LoadUiSprite("", MileageIconAssetPath), "마일리지", "+" + gainedMileage, new Vector2(812f, -140f));
AddResultStat(parent, "Time", LoadUiSprite("", TimerIconAssetPath), "도착 시간", lastResultTime.ToString("0.0") + "s", new Vector2(900f, -140f));
string distance = targetDistance > 0
? shownDistance + "/" + targetDistance + "m"
: shownDistance + "m";
AddResultStat(parent, "Distance", LoadUiSprite("", CheckpointIconAssetPath), "이동 거리", distance, new Vector2(770f, -90f));
AddResultStat(parent, "Distance", LoadUiSprite("", CheckpointIconAssetPath), "이동 거리", distance, new Vector2(986f, -140f));
}
private void AddResultTickets(RectTransform parent, MapDefinition resultMap, int rewardMileage) {
@@ -547,8 +554,8 @@ public class GameFlowManager : MonoBehaviour {
"Destination",
LoadUiSprite("", CheckpointIconAssetPath),
"목적지",
GetResultDestinationName(resultMap),
new Vector2(410f, -200f));
GetResultDestinationCityName(resultMap),
new Vector2(812f, -251f));
AddResultTicket(
parent,
@@ -556,7 +563,7 @@ public class GameFlowManager : MonoBehaviour {
lastResultCleared ? GetResultSouvenirSprite(resultMap) : LoadUiSprite("", SouvenirCollectionIconAssetPath),
"보상",
lastResultCleared ? GetResultSouvenirName(resultMap) : "다음 도전",
new Vector2(560f, -200f));
new Vector2(900f, -251f));
AddResultTicket(
parent,
@@ -564,19 +571,29 @@ public class GameFlowManager : MonoBehaviour {
LoadUiSprite("", MileageIconAssetPath),
"보유",
saveData.totalMileage + " M",
new Vector2(710f, -200f));
new Vector2(984f, -251f));
}
private void AddResultStat(RectTransform parent, string objectName, Sprite iconSprite, string label, string value, Vector2 centerPosition) {
AddResultImage(parent, "Result " + objectName + " Icon", iconSprite, centerPosition + new Vector2(0f, -4f), new Vector2(42f, 42f), true, Color.white);
AddResultText(parent, "Result " + objectName + " Value", value, centerPosition + new Vector2(-70f, -25f), new Vector2(140f, 24f), 15f, FontStyles.Bold, new Color(0.05f, 0.17f, 0.25f, 1f), TextAlignmentOptions.Center);
AddResultText(parent, "Result " + objectName + " Label", label, centerPosition + new Vector2(-70f, -48f), new Vector2(140f, 18f), 8f, FontStyles.Bold, new Color(0.42f, 0.58f, 0.64f, 0.92f), TextAlignmentOptions.Center);
AddResultImage(parent, "Result " + objectName + " Icon", iconSprite, centerPosition + new Vector2(0f, 23f), new Vector2(28f, 28f), true, Color.white);
AddResultCenteredText(parent, "Result " + objectName + " Value", value, centerPosition + new Vector2(0f, -2f), new Vector2(90f, 22f), 12f, FontStyles.Bold, new Color(0.05f, 0.17f, 0.25f, 1f), TextAlignmentOptions.Center);
AddResultCenteredText(parent, "Result " + objectName + " Label", label, centerPosition + new Vector2(0f, -25f), new Vector2(90f, 16f), 8f, FontStyles.Bold, new Color(0.42f, 0.58f, 0.64f, 0.92f), TextAlignmentOptions.Center);
}
private void AddResultTicket(RectTransform parent, string objectName, Sprite iconSprite, string label, string value, Vector2 topLeftPosition) {
AddResultImage(parent, "Result " + objectName + " Icon", iconSprite, topLeftPosition + new Vector2(28f, -40f), new Vector2(40f, 40f), true, Color.white);
AddResultText(parent, "Result " + objectName + " Label", label, topLeftPosition + new Vector2(56f, -19f), new Vector2(94f, 18f), 13f, FontStyles.Bold, new Color(0.43f, 0.58f, 0.64f, 0.96f), TextAlignmentOptions.MidlineLeft);
AddResultText(parent, "Result " + objectName + " Value", value, topLeftPosition + new Vector2(56f, -42f), new Vector2(112f, 26f), 12f, FontStyles.Bold, new Color(0.05f, 0.18f, 0.27f, 1f), TextAlignmentOptions.MidlineLeft);
private void AddResultTicket(RectTransform parent, string objectName, Sprite iconSprite, string label, string value, Vector2 centerPosition) {
AddResultImage(parent, "Result " + objectName + " Icon", iconSprite, centerPosition + new Vector2(0f, 27f), new Vector2(34f, 34f), true, Color.white);
AddResultCenteredText(parent, "Result " + objectName + " Label", label, centerPosition + new Vector2(0f, -9f), new Vector2(110f, 18f), 11f, FontStyles.Bold, new Color(0.43f, 0.58f, 0.64f, 0.96f), TextAlignmentOptions.Center);
AddResultCenteredText(parent, "Result " + objectName + " Value", value, centerPosition + new Vector2(0f, -31f), new Vector2(118f, 26f), 12f, FontStyles.Bold, new Color(0.05f, 0.18f, 0.27f, 1f), TextAlignmentOptions.Center);
}
private void AddResultRouteBox(RectTransform parent, string objectName, string code, string cityName, Vector2 centerPosition) {
AddResultCenteredText(parent, "Result " + objectName + " Airport Code", code, centerPosition + new Vector2(0f, 7f), new Vector2(150f, 48f), 34f, FontStyles.Bold, new Color(0.05f, 0.17f, 0.27f, 1f), TextAlignmentOptions.Center);
AddResultCenteredText(parent, "Result " + objectName + " City", cityName, centerPosition + new Vector2(0f, -30f), new Vector2(160f, 22f), 12f, FontStyles.Bold, new Color(0.43f, 0.58f, 0.64f, 0.96f), TextAlignmentOptions.Center);
}
private void AddResultBoardingField(RectTransform parent, string objectName, string label, string value, Vector2 centerPosition) {
AddResultCenteredText(parent, "Result " + objectName + " Label", label, centerPosition + new Vector2(0f, 13f), new Vector2(104f, 17f), 9f, FontStyles.Bold, new Color(0.43f, 0.58f, 0.64f, 0.96f), TextAlignmentOptions.Center);
AddResultCenteredText(parent, "Result " + objectName + " Value", value, centerPosition + new Vector2(0f, -12f), new Vector2(108f, 28f), 14f, FontStyles.Bold, new Color(0.05f, 0.18f, 0.27f, 1f), TextAlignmentOptions.Center);
}
private void AddResultActionButton(string label, UnityEngine.Events.UnityAction action, Vector2 position, Vector2 size, bool primary, Sprite iconSprite) {
@@ -657,27 +674,92 @@ public class GameFlowManager : MonoBehaviour {
return textComponent;
}
private string GetResultDestinationName(MapDefinition resultMap) {
private TextMeshProUGUI AddResultCenteredText(RectTransform parent, string objectName, string text, Vector2 centerPosition, Vector2 size, float fontSize, FontStyles fontStyle, Color color, TextAlignmentOptions alignment) {
Vector2 topLeftPosition = centerPosition + new Vector2(-size.x * 0.5f, size.y * 0.5f);
return AddResultText(parent, objectName, text, topLeftPosition, size, fontSize, fontStyle, color, alignment);
}
private string GetResultOriginAirportCode(MapDefinition resultMap) {
return GetAirportCode(GetResultOriginMapId(resultMap));
}
private string GetResultDestinationAirportCode(MapDefinition resultMap) {
return GetAirportCode(GetResultDestinationMapId(resultMap));
}
private string GetResultOriginCityName(MapDefinition resultMap) {
return GetAirportCityName(GetResultOriginMapId(resultMap));
}
private string GetResultDestinationCityName(MapDefinition resultMap) {
return GetAirportCityName(GetResultDestinationMapId(resultMap));
}
private MapId GetResultOriginMapId(MapDefinition resultMap) {
if(resultMap == null)
{
return "여행지";
return MapId.TutorialIncheon;
}
switch(resultMap.mapId)
return resultMap.mapId;
}
private MapId GetResultDestinationMapId(MapDefinition resultMap) {
if(resultMap == null)
{
return MapId.Japan;
}
if(resultMap.hasNextMap)
{
return resultMap.nextMapId;
}
return resultMap.mapId;
}
private string GetAirportCode(MapId mapId) {
switch(mapId)
{
case MapId.TutorialIncheon:
return "ICN";
case MapId.Japan:
return "FUK";
case MapId.China:
return "PVG";
case MapId.America:
return "LAX";
default:
return "TRP";
}
}
private string GetAirportCityName(MapId mapId) {
switch(mapId)
{
case MapId.TutorialIncheon:
return "인천공항";
case MapId.Japan:
return "일본";
return "후쿠오카";
case MapId.China:
return "중국";
return "상하이";
case MapId.America:
return "미국";
return "로스앤젤레스";
default:
return resultMap.displayName;
return "여행지";
}
}
private string GetResultFlightName(MapDefinition resultMap) {
int mapNumber = resultMap != null ? (int)resultMap.mapId + 1 : 1;
return "UNR-" + mapNumber.ToString("000");
}
private string GetResultSeatName(MapDefinition resultMap) {
int mapNumber = resultMap != null ? (int)resultMap.mapId + 1 : 1;
return (10 + mapNumber).ToString() + "A";
}
private string GetResultSouvenirName(MapDefinition resultMap) {
if(resultMap == null)
{
+13 -2
View File
@@ -8,6 +8,7 @@
| 파일 | 용도 |
| --- | --- |
| `Assets/Resources/UI_ResultBoardingPassPanel_New.png` | 현재 적용 중인 결과 화면 보딩패스형 정산 패널 배경 |
| `Assets/Resources/UI_LeftHudPassportHorizontalGridPanel.png` | 현재 적용 중인 가로형 왼쪽 여권 HUD 배경 |
| `Assets/Resources/UI_LeftHudPassportCompactPanel.png` | 오른쪽 빈 장식 영역을 줄인 왼쪽 HUD 전용 컴팩트 여권 배경 |
| `Assets/Resources/UI_LeftHudPassportPanel.png` | 이전 큰 세로형 왼쪽 여권 HUD 배경 |
@@ -101,11 +102,13 @@
## Result UI Assets
결과 화면은 여권 정산표처럼 필요한 정보만 간추려 보여줍니다.
결과 화면은 보딩패스형 정산표처럼 필요한 정보만 간추려 보여줍니다.
큰 텍스트와 수치 정보는 이미지에 박지 않고 Unity UI 텍스트/아이콘으로 얹습니다.
| 파일 | 용도 |
| --- | --- |
| `Assets/Resources/UI_LeftHudPassportHorizontalGridPanel.png` | 결과 화면 여권 정산표 배경 |
| `Assets/Resources/UI_ResultBoardingPassPanel_New.png` | 현재 결과 화면 보딩패스 정산표 배경 |
| `Assets/Resources/UI_LeftHudPassportHorizontalGridPanel.png` | 이전 결과 화면 여권 정산표 배경 및 참고 원본 |
| `Assets/Resources/UI_DepartureStamp_Red.png` | `출국 성공!` 클리어 도장 |
| `Assets/Sprites/UIIcons/UI_ClearRank.png` | 클리어 배지 |
| `Assets/Sprites/UIIcons/UI_Mileage.png` | 마일리지 스탯 |
@@ -117,6 +120,14 @@
| `Assets/Resources/Map_Tutorial_Incheon_Airport.png` | 결과 화면 뒤 인천공항 배경 |
| `Assets/Sprites/Souvenirs/` | 맵별 보상 기념품 표시 |
보딩패스 배경 구성:
- 왼쪽 큰 영역: `출국 성공!` / 실패 문구, `ICN -> FUK` 같은 이동 경로, 출국 도장
- 중앙 큰 박스: FROM/TO 공항 코드와 도시명
- 중앙 하단 4칸: 항공편, 좌석, 로컬 탑승 시간, 클래스
- 오른쪽 원 3개: 마일리지, 도착 시간, 이동 거리
- 오른쪽 하단 3칸: 목적지, 보상, 보유 마일리지
## Opening Story Assets
| 파일/폴더 | 용도 |
+6 -2
View File
@@ -96,9 +96,11 @@ HUD:
방향:
- 여행 정산표 느낌
- 보딩패스/여권 정산표 느낌
- 클리어 문구는 `출국 성공!`
- 필요한 정보만 표시
- FROM/TO 공항 코드
- 로컬 탑승 시간
- 목적지
- 획득 마일리지
- 도착 시간
@@ -107,7 +109,9 @@ HUD:
- 버튼은 클리어 시 `면세점으로`, 실패 시 `다시 도전`
- 보조 버튼은 `인트로` 대신 `다음 여행지 가기`
- 배경은 인천공항 배경을 사용
- 여권 페이지, 출국 도장, 마일리지/시간/체크포인트/기념품 아이콘, 공항 안내 패널 버튼을 사용
- 보딩패스 패널, 출국 도장, 마일리지/시간/체크포인트/기념품 아이콘, 공항 안내 패널 버튼을 사용
- 보딩패스 배경은 텍스트 없는 빈 슬롯 이미지로 유지하고, 실제 한글/숫자는 Unity UI에서 얹습니다.
- 오른쪽 원형 슬롯은 마일리지/도착 시간/이동 거리 수치를 담을 수 있도록 하단 티켓 슬롯과 가로 중심을 맞춥니다.
## DutyFreeShop
+36
View File
@@ -2,6 +2,42 @@
날짜별 수정 내용과 다음 할 일을 기록합니다.
## 2026-07-08
### 수정한 점
- 결과 화면 배경을 기존 여권 정산표에서 보딩패스형 패널로 변경
- 새 결과 화면 리소스 `Assets/Resources/UI_ResultBoardingPassPanel_New.png` 추가
- 보딩패스 배경은 글자 없는 빈 슬롯 형태로 만들고, 실제 값은 Unity UI 텍스트/아이콘으로 얹도록 구성
- 왼쪽 결과 영역에 `출국 성공!`, `ICN -> FUK` 형식의 이동 경로, 도착지명을 배치
- 중앙 큰 박스에 FROM/TO 공항 코드와 도시명을 표시
- 중앙 하단 4칸에 항공편, 좌석, 플레이어 로컬 시간 기준 탑승 시간, 클래스를 표시
- 오른쪽 원 3개에 마일리지, 도착 시간, 이동 거리를 배치
- 오른쪽 원 3개는 아래 목적지/보상/보유 마일리지 박스와 가로 중심을 맞추고, 내부 물결 장식을 제거
- 오른쪽 상단의 비행기, 경로, 별, 나침반 장식을 원 위쪽으로 올려 보딩패스 전체 구성이 자연스럽게 보이도록 정리
- 이전의 부분 덮어쓰기식 보정본은 폐기하고, 전체 이미지 편집본으로 다시 교체
- 결과 화면 공항 코드 매핑 추가
- 튜토리얼/인천: `ICN`
- 일본: `FUK`
- 중국: `PVG`
- 미국: `LAX`
- 결과 화면 텍스트 좌표를 새 보딩패스 박스 중심 기준으로 재조정
- `dotnet build Assembly-CSharp.csproj` 기준 경고 0개 / 오류 0개 확인
### 현재 문제
- 결과 화면의 세부 좌표는 Unity 실제 화면에서 한 번 더 미세 조정할 수 있음
- 새 보딩패스 이미지가 생성형 이미지 기반이라, 최종 퀄리티가 확정되면 수동 리터칭 또는 재생성이 필요할 수 있음
- 면세점 구매 아이템이 아직 장착 슬롯과 연결되지 않음
- 일본, 중국, 미국 맵의 실제 패턴과 난이도 차별화가 더 필요함
### 다음 할 일
1. Unity 디버그 메뉴의 `출국 성공` 화면에서 새 보딩패스 좌표를 실제 해상도로 확인
2. 결과 화면 좌표를 확정한 뒤 `ResultScreenView` 분리 리팩터링으로 이동
3. 면세점 구매 아이템을 장착 슬롯과 연결
4. 일본, 중국, 미국 맵의 실제 패턴과 난이도 차별화
## 2026-07-07
### 수정한 점