diff --git a/Assets/Scenes/Levels/AppleHillsOverworld.unity b/Assets/Scenes/Levels/AppleHillsOverworld.unity index f3112e13..35a42a2d 100644 --- a/Assets/Scenes/Levels/AppleHillsOverworld.unity +++ b/Assets/Scenes/Levels/AppleHillsOverworld.unity @@ -553,7 +553,10 @@ PrefabInstance: m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] - m_AddedComponents: [] + m_AddedComponents: + - targetCorrespondingSourceObject: {fileID: 6350287859698694726, guid: b5fc01af35233eb4cbeede05e50a7c34, type: 3} + insertIndex: -1 + addedObject: {fileID: 800207724} m_SourcePrefab: {fileID: 100100000, guid: b5fc01af35233eb4cbeede05e50a7c34, type: 3} --- !u!1001 &448642088 PrefabInstance: @@ -629,6 +632,29 @@ Transform: m_CorrespondingSourceObject: {fileID: 2844046668579196942, guid: b5fc01af35233eb4cbeede05e50a7c34, type: 3} m_PrefabInstance: {fileID: 368640488} m_PrefabAsset: {fileID: 0} +--- !u!1 &800207718 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 6350287859698694726, guid: b5fc01af35233eb4cbeede05e50a7c34, type: 3} + m_PrefabInstance: {fileID: 368640488} + m_PrefabAsset: {fileID: 0} +--- !u!114 &800207724 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 800207718} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 21401a3b30134380bb205964d9e5c67d, type: 3} + m_Name: + m_EditorClassIdentifier: + OnSuccess: + m_PersistentCalls: + m_Calls: [] + OnFailure: + m_PersistentCalls: + m_Calls: [] --- !u!1001 &1088965592 PrefabInstance: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/Core/GameManager.cs b/Assets/Scripts/Core/GameManager.cs index 4506cb4a..3701cfa3 100644 --- a/Assets/Scripts/Core/GameManager.cs +++ b/Assets/Scripts/Core/GameManager.cs @@ -96,4 +96,5 @@ public class GameManager : MonoBehaviour public float EndlessDescenderClampXMax => gameSettings != null ? gameSettings.endlessDescenderClampXMax : 5f; public float EndlessDescenderSpeedExponent => gameSettings != null ? gameSettings.endlessDescenderSpeedExponent : 2.5f; public GameSettings.HoldMovementMode DefaultHoldMovementMode => gameSettings != null ? gameSettings.defaultHoldMovementMode : GameSettings.HoldMovementMode.Pathfinding; + public GameObject LevelSwitchMenuPrefab => gameSettings != null ? gameSettings.levelSwitchMenuPrefab : null; } diff --git a/Assets/Scripts/Core/GameSettings.cs b/Assets/Scripts/Core/GameSettings.cs index 80e78282..8c921f14 100644 --- a/Assets/Scripts/Core/GameSettings.cs +++ b/Assets/Scripts/Core/GameSettings.cs @@ -49,6 +49,9 @@ public class GameSettings : ScriptableObject [Tooltip("Layer(s) to use for interactable objects.")] public LayerMask interactableLayerMask = -1; // Default to Everything + [Header("UI Prefabs")] + public GameObject levelSwitchMenuPrefab; + [System.Serializable] public class CombinationRule { public PickupItemData itemA; diff --git a/Assets/Scripts/Interactions/CombineWithBehavior.cs b/Assets/Scripts/Interactions/CombineWithBehavior.cs index 96bac334..bc3039b6 100644 --- a/Assets/Scripts/Interactions/CombineWithBehavior.cs +++ b/Assets/Scripts/Interactions/CombineWithBehavior.cs @@ -17,9 +17,9 @@ public class CombineWithBehavior : InteractionRequirementBase var pickup = GetComponent(); if (heldItem == null) { - DebugUIMessage.Show("You need an item to combine."); + // DebugUIMessage.Show("You need an item to combine."); OnFailure?.Invoke(); - return false; + return true; } if (pickup == null || pickup.itemData == null) { @@ -40,9 +40,9 @@ public class CombineWithBehavior : InteractionRequirementBase { string heldName = heldItem.itemName ?? "an item"; string targetName = pickup.itemData.itemName ?? "target item"; - DebugUIMessage.Show($"Cannot combine {heldName} with {targetName}."); + // DebugUIMessage.Show($"Cannot combine {heldName} with {targetName}."); OnFailure?.Invoke(); - return false; + return true; } } } diff --git a/Assets/Scripts/LevelS/LevelSwitch.cs b/Assets/Scripts/LevelS/LevelSwitch.cs index 3b76c9be..d122f16f 100644 --- a/Assets/Scripts/LevelS/LevelSwitch.cs +++ b/Assets/Scripts/LevelS/LevelSwitch.cs @@ -10,11 +10,8 @@ public class LevelSwitch : MonoBehaviour /// Data for this level switch (target scene, icon, etc). /// public LevelSwitchData switchData; - /// - /// Renderer for the switch icon. - /// - public SpriteRenderer iconRenderer; - private Interactable interactable; + private SpriteRenderer _iconRenderer; + private Interactable _interactable; private bool _isActive = true; @@ -24,12 +21,12 @@ public class LevelSwitch : MonoBehaviour void Awake() { _isActive = true; - if (iconRenderer == null) - iconRenderer = GetComponent(); - interactable = GetComponent(); - if (interactable != null) + if (_iconRenderer == null) + _iconRenderer = GetComponent(); + _interactable = GetComponent(); + if (_interactable != null) { - interactable.StartedInteraction += OnStartedInteraction; + _interactable.StartedInteraction += OnStartedInteraction; } ApplySwitchData(); } @@ -39,9 +36,9 @@ public class LevelSwitch : MonoBehaviour /// void OnDestroy() { - if (interactable != null) + if (_interactable != null) { - interactable.StartedInteraction -= OnStartedInteraction; + _interactable.StartedInteraction -= OnStartedInteraction; } } @@ -51,8 +48,8 @@ public class LevelSwitch : MonoBehaviour /// void OnValidate() { - if (iconRenderer == null) - iconRenderer = GetComponent(); + if (_iconRenderer == null) + _iconRenderer = GetComponent(); ApplySwitchData(); } #endif @@ -64,26 +61,49 @@ public class LevelSwitch : MonoBehaviour { if (switchData != null) { - if (iconRenderer != null) - iconRenderer.sprite = switchData.mapSprite; + if (_iconRenderer != null) + _iconRenderer.sprite = switchData.mapSprite; gameObject.name = switchData.targetLevelSceneName; // Optionally update other fields, e.g. description } } /// - /// Handles the start of an interaction (switches the level if active). + /// Handles the start of an interaction (shows confirmation menu and switches the level if confirmed). /// - private async void OnStartedInteraction() + private void OnStartedInteraction() { - Debug.Log($"LevelSwitch.OnInteracted: Switching to level {switchData?.targetLevelSceneName}"); - if (switchData != null && !string.IsNullOrEmpty(switchData.targetLevelSceneName) && _isActive) + if (switchData == null || string.IsNullOrEmpty(switchData.targetLevelSceneName) || !_isActive) + return; + + var menuPrefab = GameManager.Instance.LevelSwitchMenuPrefab; + if (menuPrefab == null) { - // Optionally: show loading UI here - var progress = new Progress(p => Debug.Log($"Loading progress: {p * 100:F0}%")); - await SceneManagerService.Instance.SwitchSceneAsync(switchData.targetLevelSceneName, progress); - _isActive = false; - // Optionally: hide loading UI here + Debug.LogError("LevelSwitchMenu prefab not assigned in GameSettings!"); + return; } + // Spawn the menu overlay (assume Canvas parent is handled in prefab setup) + var menuGo = Instantiate(menuPrefab); + var menu = menuGo.GetComponent(); + if (menu == null) + { + Debug.LogError("LevelSwitchMenu component missing on prefab!"); + Destroy(menuGo); + return; + } + // Setup menu with data and callbacks + menu.Setup(switchData, OnMenuConfirm, OnMenuCancel); + _isActive = false; // Prevent re-triggering until menu is closed + } + + private async void OnMenuConfirm() + { + var progress = new Progress(p => Debug.Log($"Loading progress: {p * 100:F0}%")); + await SceneManagerService.Instance.SwitchSceneAsync(switchData.targetLevelSceneName, progress); + } + + private void OnMenuCancel() + { + _isActive = true; // Allow interaction again if cancelled } } diff --git a/Assets/Scripts/LevelS/LevelSwitchMenu.cs b/Assets/Scripts/LevelS/LevelSwitchMenu.cs new file mode 100644 index 00000000..93e05ba7 --- /dev/null +++ b/Assets/Scripts/LevelS/LevelSwitchMenu.cs @@ -0,0 +1,55 @@ +using UnityEngine; +using UnityEngine.UI; +using TMPro; +using System; + +/// +/// UI overlay for confirming a level switch. Displays level info and handles confirm/cancel actions. +/// +public class LevelSwitchMenu : MonoBehaviour +{ + [Header("UI References")] + public Image iconImage; + public TMP_Text levelNameText; + public TMP_Text descriptionText; + public Button confirmButton; + public Button cancelButton; + + private Action _onConfirm; + private Action _onCancel; + private LevelSwitchData _switchData; + + /// + /// Initialize the menu with data and callbacks. + /// + public void Setup(LevelSwitchData switchData, Action onConfirm, Action onCancel) + { + _switchData = switchData; + _onConfirm = onConfirm; + _onCancel = onCancel; + if (iconImage) iconImage.sprite = switchData?.mapSprite; + if (levelNameText) levelNameText.text = switchData?.targetLevelSceneName ?? ""; + if (descriptionText) descriptionText.text = switchData?.description ?? ""; + if (confirmButton) confirmButton.onClick.AddListener(OnConfirmClicked); + if (cancelButton) cancelButton.onClick.AddListener(OnCancelClicked); + } + + private void OnDestroy() + { + if (confirmButton) confirmButton.onClick.RemoveListener(OnConfirmClicked); + if (cancelButton) cancelButton.onClick.RemoveListener(OnCancelClicked); + } + + private void OnConfirmClicked() + { + _onConfirm?.Invoke(); + Destroy(gameObject); + } + + private void OnCancelClicked() + { + _onCancel?.Invoke(); + Destroy(gameObject); + } +} + diff --git a/Assets/Scripts/LevelS/LevelSwitchMenu.cs.meta b/Assets/Scripts/LevelS/LevelSwitchMenu.cs.meta new file mode 100644 index 00000000..f001ba97 --- /dev/null +++ b/Assets/Scripts/LevelS/LevelSwitchMenu.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 662ab024f9b9403f9184b71850bfce4f +timeCreated: 1757335311 \ No newline at end of file