378 lines
18 KiB
C#
378 lines
18 KiB
C#
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
public partial class GameFlowManager {
|
|
private void ShowResult() {
|
|
if(TryLoadFlowScene(ResultSceneName))
|
|
{
|
|
return;
|
|
}
|
|
|
|
EnsureOverlay();
|
|
ClearOverlay();
|
|
SetOverlayVisible(true);
|
|
BuildResultScreen();
|
|
}
|
|
|
|
private void BuildResultScreen() {
|
|
ApplyResultAirportBackground();
|
|
|
|
MapDefinition resultMap = completedMap != null ? completedMap : currentMap;
|
|
int rewardMileage = lastResultCleared && resultMap != null ? resultMap.clearMileageReward : 0;
|
|
int gainedMileage = Mathf.Max(0, lastResultMileage) + rewardMileage;
|
|
int targetDistance = resultMap != null ? Mathf.FloorToInt(resultMap.targetDistance) : 0;
|
|
int shownDistance = targetDistance > 0
|
|
? Mathf.Clamp(Mathf.FloorToInt(lastResultDistance), 0, targetDistance)
|
|
: Mathf.Max(0, Mathf.FloorToInt(lastResultDistance));
|
|
|
|
RectTransform passportRect = AddResultPassportPanel();
|
|
AddResultHeader(passportRect, resultMap);
|
|
AddResultStats(passportRect, gainedMileage, shownDistance, targetDistance);
|
|
AddResultTickets(passportRect, resultMap, rewardMileage);
|
|
|
|
if(lastResultCleared)
|
|
{
|
|
AddResultActionButton("면세점으로", ShowDutyFreeShop, new Vector2(-166f, -282f), new Vector2(250f, 48f), true, LoadUiSprite("", DutyFreeIconAssetPath));
|
|
AddResultActionButton("다음 여행지 가기", ShowMapPreview, new Vector2(160f, -282f), new Vector2(292f, 48f), false, LoadUiSprite("", AirplaneTravelIconAssetPath));
|
|
}
|
|
else
|
|
{
|
|
AddResultActionButton("다시 도전", RetryCurrentMap, new Vector2(-166f, -282f), new Vector2(250f, 48f), true, LoadUiSprite("", CheckpointIconAssetPath));
|
|
AddResultActionButton("다음 여행지 가기", ShowMapPreview, new Vector2(160f, -282f), new Vector2(292f, 48f), false, LoadUiSprite("", AirplaneTravelIconAssetPath));
|
|
}
|
|
}
|
|
|
|
private void ApplyResultAirportBackground() {
|
|
if(overlayBackground != null)
|
|
{
|
|
overlayBackground.sprite = LoadUiSprite(ResultAirportBackgroundResourcePath, "Assets/Resources/Map_Tutorial_Incheon_Airport.png");
|
|
overlayBackground.preserveAspect = false;
|
|
overlayBackground.color = overlayBackground.sprite != null
|
|
? Color.white
|
|
: new Color(0.008f, 0.024f, 0.034f, 0.96f);
|
|
}
|
|
|
|
if(flowCamera != null)
|
|
{
|
|
flowCamera.backgroundColor = new Color(0.006f, 0.022f, 0.035f, 1f);
|
|
}
|
|
|
|
GameObject scrimObject = CreateUiObject("Result Airport Background Scrim", overlayRoot, typeof(Image));
|
|
RectTransform scrimRect = scrimObject.GetComponent<RectTransform>();
|
|
scrimRect.anchorMin = Vector2.zero;
|
|
scrimRect.anchorMax = Vector2.one;
|
|
scrimRect.offsetMin = Vector2.zero;
|
|
scrimRect.offsetMax = Vector2.zero;
|
|
|
|
Image scrimImage = scrimObject.GetComponent<Image>();
|
|
scrimImage.color = new Color(0.005f, 0.015f, 0.020f, 0.30f);
|
|
scrimImage.raycastTarget = false;
|
|
}
|
|
|
|
private RectTransform AddResultPassportPanel() {
|
|
GameObject panelObject = CreateUiObject("Result Passport Page", overlayRoot, typeof(Image));
|
|
RectTransform panelRect = panelObject.GetComponent<RectTransform>();
|
|
panelRect.anchorMin = new Vector2(0.5f, 0.5f);
|
|
panelRect.anchorMax = new Vector2(0.5f, 0.5f);
|
|
panelRect.pivot = new Vector2(0.5f, 0.5f);
|
|
panelRect.anchoredPosition = new Vector2(0f, 38f);
|
|
panelRect.sizeDelta = new Vector2(1092f, 330f);
|
|
|
|
Image panelImage = panelObject.GetComponent<Image>();
|
|
panelImage.sprite = LoadUiSprite(ResultPassportPanelResourcePath, ResultPassportPanelAssetPath);
|
|
panelImage.color = panelImage.sprite != null
|
|
? Color.white
|
|
: new Color(0.95f, 0.91f, 0.80f, 0.98f);
|
|
panelImage.preserveAspect = true;
|
|
panelImage.raycastTarget = false;
|
|
|
|
return panelRect;
|
|
}
|
|
|
|
private void AddResultHeader(RectTransform parent, MapDefinition resultMap) {
|
|
Sprite rankSprite = LoadUiSprite("", ClearRankIconAssetPath);
|
|
|
|
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);
|
|
AddResultCenteredText(parent, "Result Title", title, new Vector2(244f, -140f), new Vector2(220f, 50f), 25f, FontStyles.Bold, titleColor, TextAlignmentOptions.Center);
|
|
|
|
AddResultRouteBox(parent, "From", GetResultOriginAirportCode(resultMap), GetResultOriginCityName(resultMap), new Vector2(440f, -122f));
|
|
AddResultRouteBox(parent, "To", GetResultDestinationAirportCode(resultMap), GetResultDestinationCityName(resultMap), new Vector2(660f, -122f));
|
|
AddResultBoardingField(parent, "Flight", "항공편", GetResultFlightName(resultMap), new Vector2(400f, -253f));
|
|
AddResultBoardingField(parent, "Seat", "좌석", GetResultSeatName(resultMap), new Vector2(497f, -253f));
|
|
AddResultBoardingField(parent, "Boarding", "탑승", System.DateTime.Now.ToString("HH:mm"), new Vector2(595f, -253f));
|
|
AddResultBoardingField(parent, "Class", "클래스", lastResultCleared ? "일반석" : "대기", new Vector2(695f, -253f));
|
|
}
|
|
|
|
private void AddResultStats(RectTransform parent, int gainedMileage, int shownDistance, int targetDistance) {
|
|
AddResultStat(parent, "Mileage", LoadUiSprite("", MileageIconAssetPath), "마일리지", "+" + gainedMileage, new Vector2(812f, -140f));
|
|
AddResultStat(parent, "Time", LoadUiSprite("", TimerIconAssetPath), "도착 시간", lastResultTime.ToString("0.0") + "s", new Vector2(903f, -140f));
|
|
|
|
string distance = targetDistance > 0
|
|
? shownDistance + "/" + targetDistance + "m"
|
|
: shownDistance + "m";
|
|
AddResultStat(parent, "Distance", LoadUiSprite("", CheckpointIconAssetPath), "이동 거리", distance, new Vector2(993f, -140f));
|
|
}
|
|
|
|
private void AddResultTickets(RectTransform parent, MapDefinition resultMap, int rewardMileage) {
|
|
AddResultTicket(
|
|
parent,
|
|
"Destination",
|
|
LoadUiSprite("", CheckpointIconAssetPath),
|
|
"목적지",
|
|
GetResultDestinationCityName(resultMap),
|
|
new Vector2(812f, -251f));
|
|
|
|
AddResultTicket(
|
|
parent,
|
|
"Souvenir",
|
|
lastResultCleared ? GetResultSouvenirSprite(resultMap) : LoadUiSprite("", SouvenirCollectionIconAssetPath),
|
|
"보상",
|
|
lastResultCleared ? GetResultSouvenirName(resultMap) : "다음 도전",
|
|
new Vector2(900f, -251f));
|
|
|
|
AddResultTicket(
|
|
parent,
|
|
"Total Mileage",
|
|
LoadUiSprite("", MileageIconAssetPath),
|
|
"보유",
|
|
saveData.totalMileage + " M",
|
|
new Vector2(991f, -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, 5f), new Vector2(26f, 26f), true, Color.white);
|
|
AddResultCenteredText(parent, "Result " + objectName + " Value", value, centerPosition + new Vector2(0f, -17f), 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, -32f), 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 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, -35f), new Vector2(118f, 26f), 11f, 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) {
|
|
GameObject buttonObject = CreateUiObject("Result Button " + label, overlayRoot, typeof(Image), typeof(Button));
|
|
RectTransform buttonRect = buttonObject.GetComponent<RectTransform>();
|
|
buttonRect.anchorMin = new Vector2(0.5f, 0.5f);
|
|
buttonRect.anchorMax = new Vector2(0.5f, 0.5f);
|
|
buttonRect.pivot = new Vector2(0.5f, 0.5f);
|
|
buttonRect.anchoredPosition = position;
|
|
buttonRect.sizeDelta = size;
|
|
|
|
Image buttonImage = buttonObject.GetComponent<Image>();
|
|
buttonImage.sprite = LoadUiSprite(ResultButtonResourcePath, ResultButtonAssetPath);
|
|
buttonImage.color = buttonImage.sprite != null
|
|
? (primary ? Color.white : new Color(0.86f, 0.94f, 1f, 0.94f))
|
|
: primary
|
|
? new Color(1f, 0.82f, 0.28f, 0.98f)
|
|
: new Color(0.82f, 0.91f, 0.96f, 0.90f);
|
|
buttonImage.preserveAspect = false;
|
|
buttonImage.raycastTarget = true;
|
|
|
|
Button button = buttonObject.GetComponent<Button>();
|
|
button.onClick.AddListener(action);
|
|
|
|
if(iconSprite != null)
|
|
{
|
|
AddResultImage(buttonRect, "Result Button Icon", iconSprite, new Vector2(34f, -(size.y * 0.5f)), new Vector2(24f, 24f), true, Color.white);
|
|
}
|
|
|
|
TextMeshProUGUI buttonText = AddResultText(buttonRect, "Result Button Label", label, new Vector2(iconSprite != null ? 54f : 0f, -1f), new Vector2(iconSprite != null ? size.x - 70f : size.x, size.y), 16f, FontStyles.Bold, new Color(0.94f, 0.99f, 1f, 1f), TextAlignmentOptions.Center);
|
|
RectTransform textRect = buttonText.rectTransform;
|
|
textRect.anchorMin = new Vector2(0f, 0.5f);
|
|
textRect.anchorMax = new Vector2(0f, 0.5f);
|
|
textRect.pivot = new Vector2(0f, 0.5f);
|
|
buttonText.outlineColor = new Color(0f, 0.04f, 0.07f, 0.98f);
|
|
buttonText.outlineWidth = 0.12f;
|
|
}
|
|
|
|
private Image AddResultImage(RectTransform parent, string objectName, Sprite sprite, Vector2 position, Vector2 size, bool preserveAspect, Color color) {
|
|
GameObject imageObject = CreateUiObject(objectName, parent, typeof(Image));
|
|
RectTransform imageRect = imageObject.GetComponent<RectTransform>();
|
|
imageRect.anchorMin = new Vector2(0f, 1f);
|
|
imageRect.anchorMax = new Vector2(0f, 1f);
|
|
imageRect.pivot = new Vector2(0.5f, 0.5f);
|
|
imageRect.anchoredPosition = position;
|
|
imageRect.sizeDelta = size;
|
|
|
|
Image image = imageObject.GetComponent<Image>();
|
|
image.sprite = sprite;
|
|
image.color = sprite != null ? color : new Color(0.30f, 0.46f, 0.54f, 0.28f);
|
|
image.preserveAspect = preserveAspect;
|
|
image.raycastTarget = false;
|
|
return image;
|
|
}
|
|
|
|
private TextMeshProUGUI AddResultText(RectTransform parent, string objectName, string text, Vector2 position, Vector2 size, float fontSize, FontStyles fontStyle, Color color, TextAlignmentOptions alignment) {
|
|
GameObject textObject = CreateUiObject(objectName, parent);
|
|
RectTransform textRect = textObject.GetComponent<RectTransform>();
|
|
textRect.anchorMin = new Vector2(0f, 1f);
|
|
textRect.anchorMax = new Vector2(0f, 1f);
|
|
textRect.pivot = new Vector2(0f, 1f);
|
|
textRect.anchoredPosition = position;
|
|
textRect.sizeDelta = size;
|
|
|
|
TextMeshProUGUI textComponent = textObject.AddComponent<TextMeshProUGUI>();
|
|
textComponent.text = text;
|
|
textComponent.font = runtimeFont != null ? runtimeFont : textComponent.font;
|
|
textComponent.fontSize = fontSize;
|
|
textComponent.fontStyle = fontStyle;
|
|
textComponent.alignment = alignment;
|
|
textComponent.color = color;
|
|
textComponent.raycastTarget = false;
|
|
textComponent.textWrappingMode = TextWrappingModes.Normal;
|
|
textComponent.overflowMode = TextOverflowModes.Ellipsis;
|
|
textComponent.enableAutoSizing = true;
|
|
textComponent.fontSizeMin = Mathf.Max(8f, fontSize * 0.66f);
|
|
textComponent.fontSizeMax = fontSize;
|
|
return textComponent;
|
|
}
|
|
|
|
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 MapId.TutorialIncheon;
|
|
}
|
|
|
|
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 "후쿠오카";
|
|
case MapId.China:
|
|
return "상하이";
|
|
case MapId.America:
|
|
return "로스앤젤레스";
|
|
default:
|
|
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)
|
|
{
|
|
return "여행 도장";
|
|
}
|
|
|
|
switch(resultMap.mapId)
|
|
{
|
|
case MapId.TutorialIncheon:
|
|
return "공항 마그넷";
|
|
case MapId.Japan:
|
|
return "일본 마그넷";
|
|
case MapId.China:
|
|
return "여행 부적";
|
|
case MapId.America:
|
|
return "스카이라인";
|
|
default:
|
|
return "여행 도장";
|
|
}
|
|
}
|
|
|
|
private Sprite GetResultSouvenirSprite(MapDefinition resultMap) {
|
|
if(resultMap == null)
|
|
{
|
|
return LoadUiSprite("", SouvenirCollectionIconAssetPath);
|
|
}
|
|
|
|
switch(resultMap.mapId)
|
|
{
|
|
case MapId.TutorialIncheon:
|
|
return LoadUiSprite("", AirportSouvenirAssetPath);
|
|
case MapId.Japan:
|
|
return LoadUiSprite("", JapanSouvenirAssetPath);
|
|
case MapId.China:
|
|
return LoadUiSprite("", ChinaSouvenirAssetPath);
|
|
case MapId.America:
|
|
return LoadUiSprite("", AmericaSouvenirAssetPath);
|
|
default:
|
|
return LoadUiSprite("", SouvenirCollectionIconAssetPath);
|
|
}
|
|
}
|
|
|
|
|
|
}
|