using TMPro; using UnityEngine; using UnityEngine.UI; public partial class GameFlowManager { private void ShowDutyFreeShop() { currentScreen = FlowScreen.DutyFreeShop; gameplayActive = false; pendingStartGameplay = false; if(TryLoadFlowScene(DutyFreeShopSceneName)) { return; } EnsureOverlay(); ClearOverlay(); SetOverlayVisible(true); BuildDutyFreeShopScreen(); } private void BuildDutyFreeShopScreen() { EnsureDutyFreeStagePurchaseLimits(); ApplyDutyFreeShopBackground(); RectTransform boardRect = AddDutyFreeBoard(); AddDutyFreeHeader(boardRect); AddDutyFreeItemCard( boardRect, "도시락", DutyFreeItemType.Lunchbox, LunchboxCost, saveData.lunchboxStock, LoadUiSprite("", DutyFreeLunchboxAssetPath), BuyLunchbox, new Vector2(75f, -135f)); AddDutyFreeSupplementCard( boardRect, "영양제", SupplementCost, saveData.supplementPurchases, LoadUiSprite("", DutyFreeSupplementAssetPath), BuySupplement, new Vector2(303f, -135f)); AddDutyFreeItemCard( boardRect, "마일리지 카드", DutyFreeItemType.MileageCard, MileageCardCost, saveData.mileageCardStock, LoadUiSprite("", DutyFreeMileageCardAssetPath), BuyMileageCard, new Vector2(760f, -135f)); AddDutyFreeNextTravelButton(); } private void ApplyDutyFreeShopBackground() { if(overlayBackground != null) { overlayBackground.sprite = null; overlayBackground.preserveAspect = false; overlayBackground.color = new Color(0.018f, 0.041f, 0.052f, 0.98f); } if(flowCamera != null) { flowCamera.backgroundColor = new Color(0.018f, 0.041f, 0.052f, 1f); } AddDutyFreeBackdropImage( "Duty Free Shop Interior", LoadUiSprite(DutyFreeBackgroundResourcePath, DutyFreeBackgroundAssetPath), Vector2.zero, new Vector2(1378f, 724f), true, Color.white); GameObject scrimObject = CreateUiObject("Duty Free Background Scrim", overlayRoot, typeof(Image)); RectTransform scrimRect = scrimObject.GetComponent(); scrimRect.anchorMin = Vector2.zero; scrimRect.anchorMax = Vector2.one; scrimRect.offsetMin = Vector2.zero; scrimRect.offsetMax = Vector2.zero; Image scrimImage = scrimObject.GetComponent(); scrimImage.color = new Color(0.01f, 0.012f, 0.014f, 0.22f); scrimImage.raycastTarget = false; } private Image AddDutyFreeBackdropImage(string objectName, Sprite sprite, Vector2 position, Vector2 size, bool preserveAspect, Color color) { GameObject imageObject = CreateUiObject(objectName, overlayRoot, typeof(Image)); RectTransform imageRect = imageObject.GetComponent(); imageRect.anchorMin = new Vector2(0.5f, 0.5f); imageRect.anchorMax = new Vector2(0.5f, 0.5f); imageRect.pivot = new Vector2(0.5f, 0.5f); imageRect.anchoredPosition = position; imageRect.sizeDelta = size; Image image = imageObject.GetComponent(); 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 RectTransform AddDutyFreeBoard() { GameObject boardObject = CreateUiObject("Duty Free Product Board", overlayRoot, typeof(Image)); RectTransform boardRect = boardObject.GetComponent(); boardRect.anchorMin = new Vector2(0.5f, 0.5f); boardRect.anchorMax = new Vector2(0.5f, 0.5f); boardRect.pivot = new Vector2(0.5f, 0.5f); boardRect.anchoredPosition = new Vector2(0f, 20f); boardRect.sizeDelta = new Vector2(1038f, 552f); Image boardImage = boardObject.GetComponent(); boardImage.sprite = LoadUiSprite(DutyFreeWindowPanelResourcePath, DutyFreeWindowPanelAssetPath); boardImage.color = boardImage.sprite != null ? Color.white : new Color(0.92f, 0.98f, 1f, 0.78f); boardImage.preserveAspect = false; boardImage.raycastTarget = false; return boardRect; } private void AddDutyFreeHeader(RectTransform parent) { AddResultImage(parent, "Duty Free Equip Slots Panel", LoadUiSprite(DutyFreeEquipSlotPanelResourcePath, "Assets/Resources/UI_DutyFreeBagSlotPanel.png"), new Vector2(50f, -570f), new Vector2(276f, 124f), true, Color.white); for(int i = 0; i < 3; i++) { AddDutyFreeEquipSlot(parent, i, new Vector2(-65f + (i * 82f), -540f)); } AddDutyFreeBagUpgradeButton(parent, new Vector2(190f, -560f)); AddResultImage(parent, "Duty Free Mileage Price Tag", LoadDutyFreeResourceSprite(DutyFreePriceTagResourcePath), new Vector2(1000f, -48f), new Vector2(230f, 100f), false, Color.white); AddResultText(parent, "Duty Free Mileage Label", "보유 마일리지", new Vector2(990f, -26f), new Vector2(118f, 20f), 14f, FontStyles.Bold, new Color(0.94f, 0.99f, 1f, 0.96f), TextAlignmentOptions.MidlineLeft); AddResultText(parent, "Duty Free Mileage Value", saveData.totalMileage + " M", new Vector2(1000f, -45f), new Vector2(122f, 28f), 21f, FontStyles.Bold, new Color(1f, 0.90f, 0.38f, 1f), TextAlignmentOptions.MidlineLeft); } private void AddDutyFreeEquipSlot(RectTransform parent, int slotIndex, Vector2 topLeftPosition) { bool unlocked = slotIndex < saveData.bagSlots; DutyFreeItemType itemType = unlocked ? GetEquippedDutyFreeItem(slotIndex) : DutyFreeItemType.None; bool hasItem = itemType != DutyFreeItemType.None; GameObject slotObject = CreateUiObject("Duty Free Equip Slot " + (slotIndex + 1), parent, typeof(Image), typeof(Button)); RectTransform slotRect = slotObject.GetComponent(); slotRect.anchorMin = new Vector2(0f, 1f); slotRect.anchorMax = new Vector2(0f, 1f); slotRect.pivot = new Vector2(0f, 1f); slotRect.anchoredPosition = topLeftPosition; slotRect.sizeDelta = new Vector2(64f, 64f); Image slotImage = slotObject.GetComponent(); if(hasItem) { slotImage.sprite = LoadDutyFreeResourceSprite(DutyFreeOccupiedSlotResourcePath); slotImage.color = slotImage.sprite != null ? Color.white : new Color(0.05f, 0.16f, 0.20f, 0.88f); } else if(unlocked) { slotImage.sprite = LoadDutyFreeResourceSprite(DutyFreeActiveSlotResourcePath); slotImage.color = slotImage.sprite != null ? Color.white : new Color(0.58f, 0.36f, 0.18f, 0.88f); } else { slotImage.sprite = LoadDutyFreeResourceSprite(DutyFreeInactiveSlotResourcePath); slotImage.color = slotImage.sprite != null ? Color.white : new Color(0.35f, 0.35f, 0.35f, 0.78f); } slotImage.preserveAspect = true; slotImage.raycastTarget = hasItem; Button slotButton = slotObject.GetComponent