From ff28bd23cb76fdb2261083eab2a0c6453430db7b Mon Sep 17 00:00:00 2001 From: Michal Pikulski Date: Mon, 24 Nov 2025 10:37:40 +0100 Subject: [PATCH 1/4] Fix up eagle eye's weirdness, add option to auto clear saves --- .../AssetGroups/BlokkemonCards.asset | 12 -- Assets/Editor/Tools/AutoClearSavesOnPlay.cs | 95 +++++++++ .../Editor/Tools/AutoClearSavesOnPlay.cs.meta | 3 + Assets/Prefabs/Managers/PlayerHUD.prefab | 6 +- Assets/Scenes/Levels/Quarry.unity | 2 +- .../Core/Settings/Developer/DebugSettings.cs | 3 + .../DamianExperiments/EagleEyeBehaviour.cs | 187 +++++++++++------- Assets/Scripts/UI/PlayerHudManager.cs | 9 + Assets/Settings/Developer/DebugSettings.asset | 1 + ProjectSettings/TagManager.asset | 1 + 10 files changed, 235 insertions(+), 84 deletions(-) create mode 100644 Assets/Editor/Tools/AutoClearSavesOnPlay.cs create mode 100644 Assets/Editor/Tools/AutoClearSavesOnPlay.cs.meta diff --git a/Assets/AddressableAssetsData/AssetGroups/BlokkemonCards.asset b/Assets/AddressableAssetsData/AssetGroups/BlokkemonCards.asset index e92adc01..41c8d678 100644 --- a/Assets/AddressableAssetsData/AssetGroups/BlokkemonCards.asset +++ b/Assets/AddressableAssetsData/AssetGroups/BlokkemonCards.asset @@ -63,18 +63,6 @@ MonoBehaviour: m_SerializedLabels: - BlokkemonCard FlaggedDuringContentUpdateRestriction: 0 - - m_GUID: 4f4ec75013bc276429c2f4fa52d165e0 - m_Address: Assets/Data/Cards/Card_KalkUlation 3.asset - m_ReadOnly: 0 - m_SerializedLabels: - - BlokkemonCard - FlaggedDuringContentUpdateRestriction: 0 - - m_GUID: 53996921ed2094948aa317efe4ca6630 - m_Address: Assets/Data/Cards/Card_MormorMarmor 3.asset - m_ReadOnly: 0 - m_SerializedLabels: - - BlokkemonCard - FlaggedDuringContentUpdateRestriction: 0 - m_GUID: 73d54071304571647b3238a799d9781f m_Address: Assets/Data/Cards/Card_New Card.asset m_ReadOnly: 0 diff --git a/Assets/Editor/Tools/AutoClearSavesOnPlay.cs b/Assets/Editor/Tools/AutoClearSavesOnPlay.cs new file mode 100644 index 00000000..43540408 --- /dev/null +++ b/Assets/Editor/Tools/AutoClearSavesOnPlay.cs @@ -0,0 +1,95 @@ +using System.IO; +using UnityEditor; +using UnityEngine; +using AppleHills.Core.Settings; + +namespace Editor.Tools +{ + /// + /// Editor script that automatically clears saves before entering play mode + /// if the autoClearSaves setting is enabled in DebugSettings + /// + [InitializeOnLoad] + public static class AutoClearSavesOnPlay + { + static AutoClearSavesOnPlay() + { + EditorApplication.playModeStateChanged += OnPlayModeStateChanged; + } + + private static void OnPlayModeStateChanged(PlayModeStateChange state) + { + // Only act when entering play mode (before the scene starts playing) + if (state != PlayModeStateChange.ExitingEditMode) + return; + + // Try to load the debug settings + DebugSettings debugSettings = LoadDebugSettings(); + + if (debugSettings == null) + { + Debug.LogWarning("[AutoClearSaves] Could not find DebugSettings asset. Auto-clear saves disabled."); + return; + } + + // Check if auto-clear is enabled + if (!debugSettings.AutoClearSaves) + { + return; + } + + // Execute the clear saves logic + ClearSavesFolder(); + } + + private static DebugSettings LoadDebugSettings() + { + // Try to find the DebugSettings asset in the project + string[] guids = AssetDatabase.FindAssets("t:DebugSettings"); + + if (guids.Length == 0) + { + return null; + } + + // Load the first found DebugSettings asset + string path = AssetDatabase.GUIDToAssetPath(guids[0]); + return AssetDatabase.LoadAssetAtPath(path); + } + + private static void ClearSavesFolder() + { + // Construct the save folder path (matches SaveLoadManager.DefaultSaveFolder) + string saveFolder = Path.Combine(Application.persistentDataPath, "GameSaves"); + + if (!Directory.Exists(saveFolder)) + { + Debug.Log("[AutoClearSaves] Save folder does not exist, nothing to clear."); + return; + } + + try + { + // Delete all files in the save folder + string[] files = Directory.GetFiles(saveFolder); + int deletedCount = 0; + + foreach (string file in files) + { + File.Delete(file); + deletedCount++; + } + + if (deletedCount > 0) + { + Debug.Log($"[AutoClearSaves] Automatically deleted {deletedCount} save file(s) before entering play mode"); + } + } + catch (System.Exception ex) + { + Debug.LogError($"[AutoClearSaves] Failed to auto-clear saves: {ex}"); + } + } + } +} + diff --git a/Assets/Editor/Tools/AutoClearSavesOnPlay.cs.meta b/Assets/Editor/Tools/AutoClearSavesOnPlay.cs.meta new file mode 100644 index 00000000..63efe13e --- /dev/null +++ b/Assets/Editor/Tools/AutoClearSavesOnPlay.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c3ba01f7bb704c17bc4f22fd726f7fee +timeCreated: 1763974355 \ No newline at end of file diff --git a/Assets/Prefabs/Managers/PlayerHUD.prefab b/Assets/Prefabs/Managers/PlayerHUD.prefab index 6bacacc9..1c1b01fd 100644 --- a/Assets/Prefabs/Managers/PlayerHUD.prefab +++ b/Assets/Prefabs/Managers/PlayerHUD.prefab @@ -802,7 +802,7 @@ MonoBehaviour: m_SelectedTrigger: Selected m_DisabledTrigger: Disabled m_Interactable: 1 - m_TargetGraphic: {fileID: 0} + m_TargetGraphic: {fileID: 4189849640380816173} m_OnClick: m_PersistentCalls: m_Calls: @@ -1459,6 +1459,10 @@ PrefabInstance: serializedVersion: 3 m_TransformParent: {fileID: 2474710976069581060} m_Modifications: + - target: {fileID: 823686888810001266, guid: 428a0feafda9d6d4e87ecf43ad41dc20, type: 3} + propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_CallState + value: 1 + objectReference: {fileID: 0} - target: {fileID: 5445689290567702089, guid: 428a0feafda9d6d4e87ecf43ad41dc20, type: 3} propertyPath: m_Pivot.x value: 1 diff --git a/Assets/Scenes/Levels/Quarry.unity b/Assets/Scenes/Levels/Quarry.unity index e56cbf76..3408b28d 100644 --- a/Assets/Scenes/Levels/Quarry.unity +++ b/Assets/Scenes/Levels/Quarry.unity @@ -450296,7 +450296,7 @@ GameObject: - component: {fileID: 1137411215} m_Layer: 0 m_Name: CinemachineCamera - m_TagString: Untagged + m_TagString: MainCinemachineCamera m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 diff --git a/Assets/Scripts/Core/Settings/Developer/DebugSettings.cs b/Assets/Scripts/Core/Settings/Developer/DebugSettings.cs index ca271fec..6f2d7846 100644 --- a/Assets/Scripts/Core/Settings/Developer/DebugSettings.cs +++ b/Assets/Scripts/Core/Settings/Developer/DebugSettings.cs @@ -31,6 +31,8 @@ namespace AppleHills.Core.Settings [Header("Save Load Options")] [Tooltip("Should use save laod system?")] [SerializeField] public bool useSaveLoadSystem = true; + [Tooltip("Automatically clear all saves before entering play mode in editor")] + [SerializeField] public bool autoClearSaves = false; [Header("Logging Options")] [Tooltip("Logging level for bootstrap services")] @@ -49,6 +51,7 @@ namespace AppleHills.Core.Settings // Property getters public bool ShowDebugUiMessages => showDebugUiMessages; public bool PauseTimeOnPauseGame => pauseTimeOnPauseGame; + public bool AutoClearSaves => autoClearSaves; public override void OnValidate() { diff --git a/Assets/Scripts/DamianExperiments/EagleEyeBehaviour.cs b/Assets/Scripts/DamianExperiments/EagleEyeBehaviour.cs index 4fa772d8..6674fefc 100644 --- a/Assets/Scripts/DamianExperiments/EagleEyeBehaviour.cs +++ b/Assets/Scripts/DamianExperiments/EagleEyeBehaviour.cs @@ -1,84 +1,131 @@ +using System.Collections; using Unity.Cinemachine; using UnityEngine; -using System.Collections; -public class EagleEyeBehaviour : MonoBehaviour +namespace DamianExperiments { - [SerializeField] private CinemachineCamera virtualCamera; - [SerializeField] private CinemachineConfiner2D confiner2D; - [SerializeField] private float zoomOutOrthoSize = 30f; - [SerializeField] private float normalOrthoSize = 15f; - private float currentOrthoSize; - [SerializeField] private float transitionDuration = 0.5f; // Duration of the transition - [SerializeField] private float eagleEyeDuration = 3f; // Duration to stay zoomed out - [SerializeField] private bool disablePlayerInputDuringEagleEye = true; // Gate input disable - [SerializeField] private UnityEngine.UI.Button eagleEyeButton; // Reference to the UI button - - private Coroutine zoomCoroutine; - - public void ActivateEagleEye() + public class EagleEyeBehaviour : MonoBehaviour { - //Assigns the Virtual Camera and Confiner if not already assigned - if (virtualCamera == null) - { - virtualCamera = FindAnyObjectByType(); - } - if (confiner2D == null) - { - confiner2D = virtualCamera.GetComponent(); - } + // Serialized backing fields allow manual assignment in the inspector + private GameObject _cinecameraObject; + private CinemachineCamera _virtualCamera; + private CinemachineConfiner2D _confiner2D; - // Implementation for activating eagle eye behaviour - if (disablePlayerInputDuringEagleEye) + // Lazy-fetched properties: if null, try to find the GameObject tagged "MainCinemachineCamera" + private CinemachineCamera VirtualCamera { - currentOrthoSize = virtualCamera.Lens.OrthographicSize; - } - if (eagleEyeButton != null) - { - eagleEyeButton.interactable = false; - } - if (zoomCoroutine != null) StopCoroutine(zoomCoroutine); - zoomCoroutine = StartCoroutine(EagleEyeSequence()); - } - - private IEnumerator EagleEyeSequence() - { - if (disablePlayerInputDuringEagleEye) - { - Core.GameManager.Instance.RequestPause(this); // Disable player input - } - yield return StartCoroutine(SmoothOrthoSize(virtualCamera, zoomOutOrthoSize, transitionDuration)); - yield return new WaitForSeconds(eagleEyeDuration); - float zoomInTarget = disablePlayerInputDuringEagleEye ? currentOrthoSize : normalOrthoSize; - yield return StartCoroutine(SmoothOrthoSize(virtualCamera, zoomInTarget, transitionDuration)); - if (disablePlayerInputDuringEagleEye) - { - Core.GameManager.Instance.ReleasePause(this); // Re-enable player input - } - if (eagleEyeButton != null) - { - eagleEyeButton.interactable = true; - } - } - - private IEnumerator SmoothOrthoSize(CinemachineCamera cam, float targetSize, float duration) - { - float startSize = cam.Lens.OrthographicSize; - float elapsed = 0f; - while (elapsed < duration) - { - elapsed += Time.deltaTime; - cam.Lens.OrthographicSize = Mathf.Lerp(startSize, targetSize, elapsed / duration); - if (confiner2D != null) + get { - confiner2D.InvalidateBoundingShapeCache(); + if (_virtualCamera == null) + { + if (_cinecameraObject == null) + _cinecameraObject = GameObject.FindWithTag("MainCinemachineCamera"); + if (_cinecameraObject != null) + { + _virtualCamera = _cinecameraObject.GetComponent(); + + if (_virtualCamera == null) + Debug.LogWarning("EagleEyeBehaviour: Found object with tag 'MainCinemachineCamera' " + + "but couldn't find a CinemachineCamera component."); + } + else + { + Debug.LogWarning("EagleEyeBehaviour: No GameObject found with tag 'MainCinemachineCamera'."); + } + } + + return _virtualCamera; } - yield return null; + set => _virtualCamera = value; } - cam.Lens.OrthographicSize = targetSize; - if (confiner2D != null) + + private CinemachineConfiner2D Confiner2D { - confiner2D.InvalidateBoundingShapeCache(); + get + { + if (_confiner2D == null) + { + // If a virtual camera exists, try to pull the confiner from it + if (VirtualCamera != null) + { + _confiner2D = VirtualCamera.GetComponent(); + } + + if (_confiner2D == null) + { + Debug.LogWarning("EagleEyeBehaviour: CinemachineConfiner2D not found on the MainCinemachineCamera object."); + } + } + + return _confiner2D; + } + set => _confiner2D = value; + } + + [SerializeField] private float zoomOutOrthoSize = 30f; + [SerializeField] private float normalOrthoSize = 15f; + [SerializeField] private float transitionDuration = 0.5f; // Duration of the transition + [SerializeField] private float eagleEyeDuration = 3f; // Duration to stay zoomed out + [SerializeField] private UnityEngine.UI.Button eagleEyeButton; // Reference to the UI button + + private Coroutine _zoomCoroutine; + private Coroutine _smoothOrthoCoroutine; + private float _currentOrthoSize; + + public void ResetEagleEye() + { + if (_zoomCoroutine != null) + StopCoroutine(_zoomCoroutine); + if (_smoothOrthoCoroutine != null) + StopCoroutine(_smoothOrthoCoroutine); + if (eagleEyeButton != null) + eagleEyeButton.interactable = true; + } + + + public void ActivateEagleEye() + { + if (eagleEyeButton != null) + { + eagleEyeButton.interactable = false; + } + if (_zoomCoroutine != null) StopCoroutine(_zoomCoroutine); + _zoomCoroutine = StartCoroutine(EagleEyeSequence()); + } + + private IEnumerator EagleEyeSequence() + { + _smoothOrthoCoroutine = StartCoroutine(SmoothOrthoSize(VirtualCamera, zoomOutOrthoSize, transitionDuration)); + yield return _smoothOrthoCoroutine; + yield return new WaitForSeconds(eagleEyeDuration); + float zoomInTarget = normalOrthoSize; + _smoothOrthoCoroutine = StartCoroutine(SmoothOrthoSize(VirtualCamera, zoomInTarget, transitionDuration));; + yield return _smoothOrthoCoroutine; + if (eagleEyeButton != null) + { + eagleEyeButton.interactable = true; + } + } + + private IEnumerator SmoothOrthoSize(CinemachineCamera cam, float targetSize, float duration) + { + float startSize = cam.Lens.OrthographicSize; + float elapsed = 0f; + while (elapsed < duration) + { + elapsed += Time.deltaTime; + cam.Lens.OrthographicSize = Mathf.Lerp(startSize, targetSize, elapsed / duration); + if (Confiner2D != null) + { + Confiner2D.InvalidateBoundingShapeCache(); + } + yield return null; + } + cam.Lens.OrthographicSize = targetSize; + if (Confiner2D != null) + { + Confiner2D.InvalidateBoundingShapeCache(); + } } } } diff --git a/Assets/Scripts/UI/PlayerHudManager.cs b/Assets/Scripts/UI/PlayerHudManager.cs index 8ab8fbea..9726464d 100644 --- a/Assets/Scripts/UI/PlayerHudManager.cs +++ b/Assets/Scripts/UI/PlayerHudManager.cs @@ -8,6 +8,7 @@ using UnityEngine.UI; using System.Linq; using System.Collections.Generic; using System; +using DamianExperiments; namespace UI { @@ -308,6 +309,9 @@ namespace UI /// private void ApplyUIModeOverrides(bool visible) { + // First, reset state to neutral + ResetStateBeforeLevelLoad(); + switch (currentUIMode) { case UIMode.Overworld: @@ -336,6 +340,11 @@ namespace UI } } + protected void ResetStateBeforeLevelLoad() + { + eagleEye.GetComponent()?.ResetEagleEye(); + } + /// /// Automatically manages HUD visibility based on page stack state /// diff --git a/Assets/Settings/Developer/DebugSettings.asset b/Assets/Settings/Developer/DebugSettings.asset index 59dda546..dfb88eef 100644 --- a/Assets/Settings/Developer/DebugSettings.asset +++ b/Assets/Settings/Developer/DebugSettings.asset @@ -15,6 +15,7 @@ MonoBehaviour: showDebugUiMessages: 1 pauseTimeOnPauseGame: 0 useSaveLoadSystem: 1 + autoClearSaves: 0 bootstrapLogVerbosity: 0 settingsLogVerbosity: 0 gameManagerLogVerbosity: 0 diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset index 8d40c99f..70b32caf 100644 --- a/ProjectSettings/TagManager.asset +++ b/ProjectSettings/TagManager.asset @@ -10,6 +10,7 @@ TagManager: - Obstacle - Projectile - Target + - MainCinemachineCamera layers: - Default - TransparentFX From f0abc4760bf4e3f45a2e68fbd01bf6b6fd6e35e5 Mon Sep 17 00:00:00 2001 From: Michal Pikulski Date: Mon, 24 Nov 2025 11:07:46 +0100 Subject: [PATCH 2/4] Hide Ana-Lyse's dialogue component when taking photo, also correctly restore a hidden state with the dialogu turned off --- .../Puzzles/AnneLise/AnneLiseBaseBush.prefab | 14 +++- .../cameraSwitcherNests.cs | 2 +- .../Quarry/AnneLise/AnneLiseBushBehaviour.cs | 5 +- .../Quarry/AnneLise/HiddenState.cs | 78 +++++++++++++++++++ .../Quarry/AnneLise/HiddenState.cs.meta | 3 + 5 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 Assets/Scripts/StateMachines/Quarry/AnneLise/HiddenState.cs create mode 100644 Assets/Scripts/StateMachines/Quarry/AnneLise/HiddenState.cs.meta diff --git a/Assets/Prefabs/Puzzles/AnneLise/AnneLiseBaseBush.prefab b/Assets/Prefabs/Puzzles/AnneLise/AnneLiseBaseBush.prefab index b2b09792..67496df5 100644 --- a/Assets/Prefabs/Puzzles/AnneLise/AnneLiseBaseBush.prefab +++ b/Assets/Prefabs/Puzzles/AnneLise/AnneLiseBaseBush.prefab @@ -226,7 +226,7 @@ GameObject: - component: {fileID: 2741639361616064442} - component: {fileID: 4903273501345439385} - component: {fileID: 1054459649399154791} - - component: {fileID: 7319925080429004531} + - component: {fileID: 61210891595976786} m_Layer: 10 m_Name: Hidden m_TagString: Untagged @@ -451,7 +451,7 @@ MonoBehaviour: audioSource: {fileID: 0} clipPriority: 0 sourcePriority: 1 ---- !u!114 &7319925080429004531 +--- !u!114 &61210891595976786 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -460,9 +460,9 @@ MonoBehaviour: m_GameObject: {fileID: 1011363502278351410} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 95e46aacea5b42888ee7881894193c11, type: 3} + m_Script: {fileID: 11500000, guid: 1fa347bfb45f473f8639842928f8cfa1, type: 3} m_Name: - m_EditorClassIdentifier: AppleHillsScripts::Core.SaveLoad.AppleState + m_EditorClassIdentifier: AppleHillsScripts::StateMachines.Quarry.AnneLise.HiddenState --- !u!1 &1674229500073894281 GameObject: m_ObjectHideFlags: 0 @@ -830,6 +830,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 603ecc4a6ab6bb84c8cb9773fa310b69, type: 3} m_Name: m_EditorClassIdentifier: '::' + dialogueCanvas: {fileID: 7042752134100908030} --- !u!114 &1193493154550576580 MonoBehaviour: m_ObjectHideFlags: 0 @@ -1740,3 +1741,8 @@ RectTransform: m_CorrespondingSourceObject: {fileID: 3484825090253933040, guid: a8b0a1c6cf21352439dc24d3b03182db, type: 3} m_PrefabInstance: {fileID: 4289827099693551234} m_PrefabAsset: {fileID: 0} +--- !u!1 &7042752134100908030 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 6499933157207406972, guid: a8b0a1c6cf21352439dc24d3b03182db, type: 3} + m_PrefabInstance: {fileID: 4289827099693551234} + m_PrefabAsset: {fileID: 0} diff --git a/Assets/Scripts/DamianExperiments/SoundBirdPuzzleSection/cameraSwitcherNests.cs b/Assets/Scripts/DamianExperiments/SoundBirdPuzzleSection/cameraSwitcherNests.cs index 59c5d709..c55b6c22 100644 --- a/Assets/Scripts/DamianExperiments/SoundBirdPuzzleSection/cameraSwitcherNests.cs +++ b/Assets/Scripts/DamianExperiments/SoundBirdPuzzleSection/cameraSwitcherNests.cs @@ -30,7 +30,7 @@ public class cameraSwitcherNailBird : MonoBehaviour private void OnTriggerExit2D(Collider2D other) { - if (other.CompareTag("Player")) + if (other.CompareTag("Player") && gameObject.activeInHierarchy) { playerInsideCount--; if (playerInsideCount == 0 && virtualCamera != null) diff --git a/Assets/Scripts/StateMachines/Quarry/AnneLise/AnneLiseBushBehaviour.cs b/Assets/Scripts/StateMachines/Quarry/AnneLise/AnneLiseBushBehaviour.cs index 2553c719..c9905088 100644 --- a/Assets/Scripts/StateMachines/Quarry/AnneLise/AnneLiseBushBehaviour.cs +++ b/Assets/Scripts/StateMachines/Quarry/AnneLise/AnneLiseBushBehaviour.cs @@ -6,7 +6,9 @@ namespace StateMachines.Quarry.AnneLise { public class AnneLiseBushBehaviour : MonoBehaviour { - + [SerializeField] private GameObject dialogueCanvas; + + private AppleMachine _anneLiseBushStateMachine; // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() @@ -16,6 +18,7 @@ namespace StateMachines.Quarry.AnneLise public void TakePhoto() { + dialogueCanvas?.SetActive(false); _anneLiseBushStateMachine.ChangeState("TakePhoto"); } } diff --git a/Assets/Scripts/StateMachines/Quarry/AnneLise/HiddenState.cs b/Assets/Scripts/StateMachines/Quarry/AnneLise/HiddenState.cs new file mode 100644 index 00000000..4ecf39c8 --- /dev/null +++ b/Assets/Scripts/StateMachines/Quarry/AnneLise/HiddenState.cs @@ -0,0 +1,78 @@ +using Core.SaveLoad; +using UnityEngine; + +namespace StateMachines.Quarry.AnneLise +{ + /// + /// Hidden state for Anne Lise that saves/restores the DialogueCanvas active state + /// + public class HiddenState : AppleState + { + private GameObject _dialogueCanvas; + + /// + /// Serializable data for the hidden state + /// + [System.Serializable] + private class HiddenStateData + { + public bool wasDialogueCanvasActive; + } + + private void Awake() + { + // Find the immediate child called "DialogueCanvas" + Transform childTransform = transform.Find("DialogueCanvas"); + if (childTransform != null) + { + _dialogueCanvas = childTransform.gameObject; + } + else + { + Debug.LogWarning($"[HiddenState] DialogueCanvas child not found on {gameObject.name}"); + } + } + + public override string SerializeState() + { + if (_dialogueCanvas == null) + { + Debug.LogWarning("[HiddenState] Cannot serialize state - DialogueCanvas is null"); + return ""; + } + + HiddenStateData data = new HiddenStateData + { + wasDialogueCanvasActive = _dialogueCanvas.activeSelf + }; + + return JsonUtility.ToJson(data); + } + + public override void OnRestoreState(string data) + { + if (string.IsNullOrEmpty(data)) + { + Debug.LogWarning("[HiddenState] No data to restore"); + return; + } + + if (_dialogueCanvas == null) + { + Debug.LogWarning("[HiddenState] Cannot restore state - DialogueCanvas is null"); + return; + } + + try + { + HiddenStateData stateData = JsonUtility.FromJson(data); + _dialogueCanvas.SetActive(stateData.wasDialogueCanvasActive); + Debug.Log($"[HiddenState] Restored DialogueCanvas active state to: {stateData.wasDialogueCanvasActive}"); + } + catch (System.Exception ex) + { + Debug.LogError($"[HiddenState] Failed to restore state: {ex.Message}"); + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/StateMachines/Quarry/AnneLise/HiddenState.cs.meta b/Assets/Scripts/StateMachines/Quarry/AnneLise/HiddenState.cs.meta new file mode 100644 index 00000000..f7cd9b78 --- /dev/null +++ b/Assets/Scripts/StateMachines/Quarry/AnneLise/HiddenState.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1fa347bfb45f473f8639842928f8cfa1 +timeCreated: 1763978213 \ No newline at end of file From e33de5da3d359e07fe483c6a50b706d17e77cb15 Mon Sep 17 00:00:00 2001 From: Michal Pikulski Date: Mon, 24 Nov 2025 11:41:47 +0100 Subject: [PATCH 3/4] Fix the sound bird interactaiblity issues. --- .../Settings/DeveloperSettingsEditorWindow.cs | 68 ++++-- Assets/Prefabs/Environment/SoundBird.prefab | 223 +++++++++--------- Assets/Scenes/Levels/Quarry.unity | 217 +---------------- .../Scripts/Core/SaveLoad/SaveLoadManager.cs | 10 +- .../Core/Settings/Developer/DebugSettings.cs | 6 +- Assets/Scripts/Interactions/Interactable.cs | 13 + .../StateMachines/Quarry/SoundBird.meta | 8 + .../Quarry/SoundBird/IdleState.cs | 45 ++++ .../Quarry/SoundBird/IdleState.cs.meta | 2 + Assets/Settings/Developer/DebugSettings.asset | 1 + 10 files changed, 252 insertions(+), 341 deletions(-) create mode 100644 Assets/Scripts/StateMachines/Quarry/SoundBird.meta create mode 100644 Assets/Scripts/StateMachines/Quarry/SoundBird/IdleState.cs create mode 100644 Assets/Scripts/StateMachines/Quarry/SoundBird/IdleState.cs.meta diff --git a/Assets/Editor/Settings/DeveloperSettingsEditorWindow.cs b/Assets/Editor/Settings/DeveloperSettingsEditorWindow.cs index 0a29302f..6ee5f482 100644 --- a/Assets/Editor/Settings/DeveloperSettingsEditorWindow.cs +++ b/Assets/Editor/Settings/DeveloperSettingsEditorWindow.cs @@ -2,7 +2,6 @@ using UnityEditor; using System.Collections.Generic; using System.Linq; -using System.IO; namespace AppleHills.Core.Settings.Editor { @@ -164,23 +163,31 @@ namespace AppleHills.Core.Settings.Editor EditorGUILayout.Space(10); - // Draw all properties - SerializedProperty property = serializedObj.GetIterator(); - bool enterChildren = true; - while (property.NextVisible(enterChildren)) + // Special handling for DebugSettings + if (settings is DebugSettings) { - enterChildren = false; - - // Skip the script field - if (property.name == "m_Script") continue; - - // Group headers - if (property.isArray && property.propertyType == SerializedPropertyType.Generic) + DrawDebugSettingsEditor(serializedObj, settings as DebugSettings); + } + else + { + // Draw all properties for other settings types + SerializedProperty property = serializedObj.GetIterator(); + bool enterChildren = true; + while (property.NextVisible(enterChildren)) { - EditorGUILayout.LabelField(property.displayName, EditorStyles.boldLabel); + enterChildren = false; + + // Skip the script field + if (property.name == "m_Script") continue; + + // Group headers + if (property.isArray && property.propertyType == SerializedPropertyType.Generic) + { + EditorGUILayout.LabelField(property.displayName, EditorStyles.boldLabel); + } + + EditorGUILayout.PropertyField(property, true); } - - EditorGUILayout.PropertyField(property, true); } // Apply changes @@ -196,6 +203,37 @@ namespace AppleHills.Core.Settings.Editor } } + private void DrawDebugSettingsEditor(SerializedObject serializedObj, DebugSettings debugSettings) + { + SerializedProperty property = serializedObj.GetIterator(); + bool enterChildren = true; + bool useSaveLoadSystem = debugSettings.UseSaveLoadSystem; + + while (property.NextVisible(enterChildren)) + { + enterChildren = false; + + // Skip the script field + if (property.name == "m_Script") continue; + + // Check if this property should be disabled + bool shouldDisable = false; + if (!useSaveLoadSystem) + { + // Disable save-load related options when useSaveLoadSystem is false + if (property.name == "autoClearSaves" || property.name == "dontSaveOnQuit") + { + shouldDisable = true; + } + } + + // Disable GUI for dependent fields + EditorGUI.BeginDisabledGroup(shouldDisable); + EditorGUILayout.PropertyField(property, true); + EditorGUI.EndDisabledGroup(); + } + } + // Helper method to highlight important fields private void DrawHighlightedProperty(SerializedProperty property, string tooltip = null) { diff --git a/Assets/Prefabs/Environment/SoundBird.prefab b/Assets/Prefabs/Environment/SoundBird.prefab index 8d87a7c6..364381fc 100644 --- a/Assets/Prefabs/Environment/SoundBird.prefab +++ b/Assets/Prefabs/Environment/SoundBird.prefab @@ -9,7 +9,7 @@ GameObject: serializedVersion: 6 m_Component: - component: {fileID: 1702819536151974707} - m_Layer: 10 + m_Layer: 0 m_Name: AnnaLiseSpotSong m_TagString: Untagged m_Icon: {fileID: 0} @@ -41,13 +41,11 @@ GameObject: m_Component: - component: {fileID: 2523333015159032981} - component: {fileID: 8875860401447896107} - - component: {fileID: 5057760771402457000} - - component: {fileID: 2433130051631076285} - component: {fileID: 7290110366808972859} - component: {fileID: 9196152289301358918} - - component: {fileID: 2596311128101197840} - m_Layer: 10 - m_Name: SoundBird_Slot + - component: {fileID: 7004860270194965002} + m_Layer: 0 + m_Name: SoundBird m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -68,6 +66,7 @@ Transform: m_Children: - {fileID: 3907351184805552114} - {fileID: 1702819536151974707} + - {fileID: 2513116580733004004} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!212 &8875860401447896107 @@ -128,109 +127,6 @@ SpriteRenderer: m_WasSpriteAssigned: 1 m_MaskInteraction: 0 m_SpriteSortPoint: 0 ---- !u!61 &5057760771402457000 -BoxCollider2D: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 588897581313790951} - m_Enabled: 1 - serializedVersion: 3 - m_Density: 1 - m_Material: {fileID: 0} - m_IncludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_ExcludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_LayerOverridePriority: 0 - m_ForceSendLayers: - serializedVersion: 2 - m_Bits: 4294967295 - m_ForceReceiveLayers: - serializedVersion: 2 - m_Bits: 4294967295 - m_ContactCaptureLayers: - serializedVersion: 2 - m_Bits: 4294967295 - m_CallbackLayers: - serializedVersion: 2 - m_Bits: 4294967295 - m_IsTrigger: 0 - m_UsedByEffector: 0 - m_CompositeOperation: 0 - m_CompositeOrder: 0 - m_Offset: {x: 0, y: 1.2} - m_SpriteTilingProperty: - border: {x: 0, y: 0, z: 0, w: 0} - pivot: {x: 0.5, y: 0.5} - oldSize: {x: 1.86, y: 3.25} - newSize: {x: 2.21, y: 3.91} - adaptiveTilingThreshold: 0.5 - drawMode: 0 - adaptiveTiling: 0 - m_AutoTiling: 0 - m_Size: {x: 3.5, y: 4.5} - m_EdgeRadius: 0 ---- !u!114 &2433130051631076285 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 588897581313790951} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ec1a2e6e32f746c4990c579e13b79104, type: 3} - m_Name: - m_EditorClassIdentifier: - isOneTime: 0 - cooldown: -1 - characterToInteract: 2 - interactionStarted: - m_PersistentCalls: - m_Calls: [] - interactionInterrupted: - m_PersistentCalls: - m_Calls: [] - characterArrived: - m_PersistentCalls: - m_Calls: [] - interactionComplete: - m_PersistentCalls: - m_Calls: [] - itemData: {fileID: 11400000, guid: d28f5774afad9d14f823601707150700, type: 2} - iconRenderer: {fileID: 8875860401447896107} - slottedItemRenderers: [] - onItemSlotted: - m_PersistentCalls: - m_Calls: [] - onItemSlotRemoved: - m_PersistentCalls: - m_Calls: [] - onCorrectItemSlotted: - m_PersistentCalls: - m_Calls: - - m_Target: {fileID: 0} - m_TargetAssemblyTypeName: AnneLiseBehaviour, AppleHillsScripts - m_MethodName: GotoSpot - m_Mode: 2 - m_Arguments: - m_ObjectArgument: {fileID: 588897581313790951} - m_ObjectArgumentAssemblyTypeName: UnityEngine.GameObject, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: - m_BoolArgument: 0 - m_CallState: 2 - onIncorrectItemSlotted: - m_PersistentCalls: - m_Calls: [] - onForbiddenItemSlotted: - m_PersistentCalls: - m_Calls: [] --- !u!114 &7290110366808972859 MonoBehaviour: m_ObjectHideFlags: 0 @@ -267,7 +163,7 @@ Animator: m_AllowConstantClipSamplingOptimization: 1 m_KeepAnimatorStateOnDisable: 0 m_WriteDefaultValuesOnDisable: 0 ---- !u!114 &2596311128101197840 +--- !u!114 &7004860270194965002 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -276,9 +172,10 @@ MonoBehaviour: m_GameObject: {fileID: 588897581313790951} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 95e46aacea5b42888ee7881894193c11, type: 3} + m_Script: {fileID: 11500000, guid: cfd3b894d78129b4aa5310e5ce9cceae, type: 3} m_Name: - m_EditorClassIdentifier: AppleHillsScripts::Core.SaveLoad.AppleState + m_EditorClassIdentifier: AppleHillsScripts::StateMachines.Quarry.SoundBird.IdleState + itemSlot: {fileID: 0} --- !u!1 &4624889622840393752 GameObject: m_ObjectHideFlags: 0 @@ -304,13 +201,13 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 4624889622840393752} serializedVersion: 2 - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: -0.28, y: 0.57, z: 0} - m_LocalScale: {x: 0.6666667, y: 0.6666667, z: 0.6666667} + m_LocalRotation: {x: 0, y: 0, z: -0.075422555, w: 0.9971517} + m_LocalPosition: {x: -0.27, y: 2.37, z: 0} + m_LocalScale: {x: 0.336075, y: 0.336075, z: 0.336075} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2523333015159032981} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: -8.651} --- !u!212 &6941190210788968874 SpriteRenderer: m_ObjectHideFlags: 0 @@ -369,3 +266,97 @@ SpriteRenderer: m_WasSpriteAssigned: 0 m_MaskInteraction: 0 m_SpriteSortPoint: 0 +--- !u!1 &6117389795918759898 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2513116580733004004} + m_Layer: 0 + m_Name: AnimContainer + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2513116580733004004 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6117389795918759898} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0.13, y: 3.48, z: 0} + m_LocalScale: {x: 0.33, y: 0.33, z: 0.33} + m_ConstrainProportionsScale: 1 + m_Children: + - {fileID: 5133773671673172183} + m_Father: {fileID: 2523333015159032981} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1001 &814760252274833115 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 2513116580733004004} + m_Modifications: + - target: {fileID: 5383276844808284485, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} + propertyPath: m_Name + value: NextStepIndicator + objectReference: {fileID: 0} + - target: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} +--- !u!4 &5133773671673172183 stripped +Transform: + m_CorrespondingSourceObject: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} + m_PrefabInstance: {fileID: 814760252274833115} + m_PrefabAsset: {fileID: 0} diff --git a/Assets/Scenes/Levels/Quarry.unity b/Assets/Scenes/Levels/Quarry.unity index 3408b28d..e6df4287 100644 --- a/Assets/Scenes/Levels/Quarry.unity +++ b/Assets/Scenes/Levels/Quarry.unity @@ -432118,72 +432118,10 @@ Transform: m_CorrespondingSourceObject: {fileID: 9067462609398217044, guid: 6cbcaf4eb20e63e4fb462f6fb1ada3a7, type: 3} m_PrefabInstance: {fileID: 286519576} m_PrefabAsset: {fileID: 0} ---- !u!1001 &287904381 -PrefabInstance: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_Modification: - serializedVersion: 3 - m_TransformParent: {fileID: 726450010} - m_Modifications: - - target: {fileID: 5383276844808284485, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} - propertyPath: m_Name - value: NextStepIndicator - objectReference: {fileID: 0} - - target: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} - propertyPath: m_LocalPosition.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} - propertyPath: m_LocalPosition.y - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} - propertyPath: m_LocalPosition.z - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} - propertyPath: m_LocalRotation.w - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} - propertyPath: m_LocalRotation.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} - propertyPath: m_LocalRotation.y - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} - propertyPath: m_LocalRotation.z - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} - propertyPath: m_LocalEulerAnglesHint.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} - propertyPath: m_LocalEulerAnglesHint.y - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} - propertyPath: m_LocalEulerAnglesHint.z - value: 0 - objectReference: {fileID: 0} - m_RemovedComponents: [] - m_RemovedGameObjects: [] - m_AddedGameObjects: [] - m_AddedComponents: [] - m_SourcePrefab: {fileID: 100100000, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} ---- !u!4 &287904382 stripped -Transform: - m_CorrespondingSourceObject: {fileID: 5507990123417429516, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} - m_PrefabInstance: {fileID: 287904381} - m_PrefabAsset: {fileID: 0} --- !u!1 &287904383 stripped GameObject: - m_CorrespondingSourceObject: {fileID: 5383276844808284485, guid: afbb486e5456a20479aee4cf8bc949b6, type: 3} - m_PrefabInstance: {fileID: 287904381} + m_CorrespondingSourceObject: {fileID: 4754571837807058846, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} + m_PrefabInstance: {fileID: 1399567329} m_PrefabAsset: {fileID: 0} --- !u!1001 &289703776 PrefabInstance: @@ -442023,38 +441961,6 @@ MonoBehaviour: audioSource: {fileID: 0} clipPriority: 0 sourcePriority: 0 ---- !u!1 &726450009 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 726450010} - m_Layer: 0 - m_Name: AnimContainer - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &726450010 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 726450009} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0.13, y: 3.48, z: 0} - m_LocalScale: {x: 0.33, y: 0.33, z: 0.33} - m_ConstrainProportionsScale: 1 - m_Children: - - {fileID: 287904382} - m_Father: {fileID: 1399567330} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!4 &733706664 stripped Transform: m_CorrespondingSourceObject: {fileID: 6078012632802010276, guid: 3346526f3046f424196615241a307104, type: 3} @@ -452521,7 +452427,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 1 + m_IsActive: 0 --- !u!4 &1252594309 Transform: m_ObjectHideFlags: 0 @@ -455783,74 +455689,10 @@ PrefabInstance: serializedVersion: 3 m_TransformParent: {fileID: 368957768} m_Modifications: - - target: {fileID: 22512726373136855, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: m_Layer - value: 0 - objectReference: {fileID: 0} - target: {fileID: 588897581313790951, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} propertyPath: m_Name value: SoundBird_Slot objectReference: {fileID: 0} - - target: {fileID: 588897581313790951, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: m_Layer - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 588897581313790951, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: m_IsActive - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 2433130051631076285, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: onCorrectItemSlotted.m_PersistentCalls.m_Calls.Array.size - value: 2 - objectReference: {fileID: 0} - - target: {fileID: 2433130051631076285, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: onCorrectItemSlotted.m_PersistentCalls.m_Calls.Array.data[0].m_Mode - value: 6 - objectReference: {fileID: 0} - - target: {fileID: 2433130051631076285, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: onCorrectItemSlotted.m_PersistentCalls.m_Calls.Array.data[1].m_Mode - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 2433130051631076285, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: onCorrectItemSlotted.m_PersistentCalls.m_Calls.Array.data[0].m_Target - value: - objectReference: {fileID: 0} - - target: {fileID: 2433130051631076285, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: onCorrectItemSlotted.m_PersistentCalls.m_Calls.Array.data[1].m_Target - value: - objectReference: {fileID: 2078227529} - - target: {fileID: 2433130051631076285, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: onCorrectItemSlotted.m_PersistentCalls.m_Calls.Array.data[1].m_CallState - value: 2 - objectReference: {fileID: 0} - - target: {fileID: 2433130051631076285, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: onCorrectItemSlotted.m_PersistentCalls.m_Calls.Array.data[0].m_MethodName - value: birdCanHear - objectReference: {fileID: 0} - - target: {fileID: 2433130051631076285, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: onCorrectItemSlotted.m_PersistentCalls.m_Calls.Array.data[1].m_MethodName - value: TakePhoto - objectReference: {fileID: 0} - - target: {fileID: 2433130051631076285, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: onCorrectItemSlotted.m_PersistentCalls.m_Calls.Array.data[0].m_TargetAssemblyTypeName - value: soundBird_CanFly, AppleHillsScripts - objectReference: {fileID: 0} - - target: {fileID: 2433130051631076285, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: onCorrectItemSlotted.m_PersistentCalls.m_Calls.Array.data[1].m_TargetAssemblyTypeName - value: StateMachines.Quarry.AnneLise.AnneLiseBushBehaviour, AppleHillsScripts - objectReference: {fileID: 0} - - target: {fileID: 2433130051631076285, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: onCorrectItemSlotted.m_PersistentCalls.m_Calls.Array.data[0].m_Arguments.m_ObjectArgument - value: - objectReference: {fileID: 0} - - target: {fileID: 2433130051631076285, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: onCorrectItemSlotted.m_PersistentCalls.m_Calls.Array.data[0].m_Arguments.m_ObjectArgumentAssemblyTypeName - value: UnityEngine.Object, UnityEngine - objectReference: {fileID: 0} - - target: {fileID: 2433130051631076285, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: onCorrectItemSlotted.m_PersistentCalls.m_Calls.Array.data[1].m_Arguments.m_ObjectArgumentAssemblyTypeName - value: UnityEngine.Object, UnityEngine - objectReference: {fileID: 0} - target: {fileID: 2523333015159032981, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} propertyPath: m_LocalPosition.x value: 0.04 @@ -455891,54 +455733,13 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} - - target: {fileID: 3907351184805552114, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: m_LocalScale.x - value: 0.336075 - objectReference: {fileID: 0} - - target: {fileID: 3907351184805552114, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: m_LocalScale.y - value: 0.336075 - objectReference: {fileID: 0} - - target: {fileID: 3907351184805552114, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: m_LocalScale.z - value: 0.336075 - objectReference: {fileID: 0} - - target: {fileID: 3907351184805552114, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: m_LocalPosition.x - value: -0.27 - objectReference: {fileID: 0} - - target: {fileID: 3907351184805552114, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: m_LocalPosition.y - value: 2.37 - objectReference: {fileID: 0} - - target: {fileID: 3907351184805552114, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: m_LocalRotation.w - value: 0.9971517 - objectReference: {fileID: 0} - - target: {fileID: 3907351184805552114, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: m_LocalRotation.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 3907351184805552114, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: m_LocalRotation.y - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 3907351184805552114, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: m_LocalRotation.z - value: -0.075422555 - objectReference: {fileID: 0} - - target: {fileID: 3907351184805552114, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - propertyPath: m_LocalEulerAnglesHint.z - value: -8.651 - objectReference: {fileID: 0} - m_RemovedComponents: - - {fileID: 2433130051631076285, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - - {fileID: 5057760771402457000, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} + - target: {fileID: 7004860270194965002, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} + propertyPath: itemSlot + value: + objectReference: {fileID: 1923065567} + m_RemovedComponents: [] m_RemovedGameObjects: [] - m_AddedGameObjects: - - targetCorrespondingSourceObject: {fileID: 2523333015159032981, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} - insertIndex: -1 - addedObject: {fileID: 726450010} + m_AddedGameObjects: [] m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 9ad58c5e86338824db8a6daebdb432b5, type: 3} --- !u!4 &1399567330 stripped diff --git a/Assets/Scripts/Core/SaveLoad/SaveLoadManager.cs b/Assets/Scripts/Core/SaveLoad/SaveLoadManager.cs index 78a9d3d1..4b6ec769 100644 --- a/Assets/Scripts/Core/SaveLoad/SaveLoadManager.cs +++ b/Assets/Scripts/Core/SaveLoad/SaveLoadManager.cs @@ -85,9 +85,17 @@ namespace Core.SaveLoad private void OnApplicationQuit() { - if (DeveloperSettingsProvider.Instance.GetSettings().useSaveLoadSystem) + var debugSettings = DeveloperSettingsProvider.Instance.GetSettings(); + + // Only save if the save system is enabled AND dontSaveOnQuit is false + if (debugSettings.UseSaveLoadSystem && !debugSettings.DontSaveOnQuit) { Save(); + Logging.Debug("[SaveLoadManager] Saving on application quit"); + } + else if (debugSettings.DontSaveOnQuit) + { + Logging.Debug("[SaveLoadManager] Skipping save on quit (dontSaveOnQuit enabled)"); } } diff --git a/Assets/Scripts/Core/Settings/Developer/DebugSettings.cs b/Assets/Scripts/Core/Settings/Developer/DebugSettings.cs index 6f2d7846..19f8b678 100644 --- a/Assets/Scripts/Core/Settings/Developer/DebugSettings.cs +++ b/Assets/Scripts/Core/Settings/Developer/DebugSettings.cs @@ -29,10 +29,12 @@ namespace AppleHills.Core.Settings [SerializeField] public bool pauseTimeOnPauseGame = true; [Header("Save Load Options")] - [Tooltip("Should use save laod system?")] + [Tooltip("Should use save load system?")] [SerializeField] public bool useSaveLoadSystem = true; [Tooltip("Automatically clear all saves before entering play mode in editor")] [SerializeField] public bool autoClearSaves = false; + [Tooltip("Load saves on start but don't save/overwrite data on exit")] + [SerializeField] public bool dontSaveOnQuit = false; [Header("Logging Options")] [Tooltip("Logging level for bootstrap services")] @@ -51,7 +53,9 @@ namespace AppleHills.Core.Settings // Property getters public bool ShowDebugUiMessages => showDebugUiMessages; public bool PauseTimeOnPauseGame => pauseTimeOnPauseGame; + public bool UseSaveLoadSystem => useSaveLoadSystem; public bool AutoClearSaves => autoClearSaves; + public bool DontSaveOnQuit => dontSaveOnQuit; public override void OnValidate() { diff --git a/Assets/Scripts/Interactions/Interactable.cs b/Assets/Scripts/Interactions/Interactable.cs index d97f7c3a..0903a7cd 100644 --- a/Assets/Scripts/Interactions/Interactable.cs +++ b/Assets/Scripts/Interactions/Interactable.cs @@ -38,6 +38,11 @@ namespace Interactions protected FollowerController FollowerController; private bool isActive = true; + /// + /// Gets whether this interactable is currently active (can be clicked) + /// + public bool IsActive => isActive; + // Action component system private List _registeredActions = new List(); @@ -443,6 +448,14 @@ namespace Interactions isActive = true; } + /// + /// Enable or disable this interactable + /// + public void SetActive(bool active) + { + isActive = active; + } + #endregion #region Legacy Methods & Compatibility diff --git a/Assets/Scripts/StateMachines/Quarry/SoundBird.meta b/Assets/Scripts/StateMachines/Quarry/SoundBird.meta new file mode 100644 index 00000000..8b604201 --- /dev/null +++ b/Assets/Scripts/StateMachines/Quarry/SoundBird.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 81aa592db4b598c4cbfb7faf604e0d62 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/StateMachines/Quarry/SoundBird/IdleState.cs b/Assets/Scripts/StateMachines/Quarry/SoundBird/IdleState.cs new file mode 100644 index 00000000..2b446fa1 --- /dev/null +++ b/Assets/Scripts/StateMachines/Quarry/SoundBird/IdleState.cs @@ -0,0 +1,45 @@ +using Core.SaveLoad; +using Interactions; +using UnityEngine; + +namespace StateMachines.Quarry.SoundBird +{ + /// + /// Idle state for the Sound Bird - bird is landed and slot is interactable + /// + public class IdleState : AppleState + { + [Header("Slot Reference")] + [Tooltip("The item slot that should be enabled when the bird is idle")] + [SerializeField] private ItemSlot itemSlot; + + public override void OnEnterState() + { + // Enable the slot when the bird lands (enters idle) + if (itemSlot != null) + { + itemSlot.SetActive(true); + Debug.Log($"[IdleState] Enabled ItemSlot: {itemSlot.gameObject.name}"); + } + else + { + Debug.LogWarning("[IdleState] ItemSlot reference is null - cannot enable slot"); + } + } + + private void OnDisable() + { + // Disable the slot when the bird takes off + if (itemSlot != null) + { + itemSlot.SetActive(false); + Debug.Log($"[IdleState] Disabled ItemSlot: {itemSlot.gameObject.name}"); + } + else + { + Debug.LogWarning("[IdleState] ItemSlot reference is null - cannot disable slot"); + } + } + } +} + diff --git a/Assets/Scripts/StateMachines/Quarry/SoundBird/IdleState.cs.meta b/Assets/Scripts/StateMachines/Quarry/SoundBird/IdleState.cs.meta new file mode 100644 index 00000000..4d4b9c01 --- /dev/null +++ b/Assets/Scripts/StateMachines/Quarry/SoundBird/IdleState.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: cfd3b894d78129b4aa5310e5ce9cceae \ No newline at end of file diff --git a/Assets/Settings/Developer/DebugSettings.asset b/Assets/Settings/Developer/DebugSettings.asset index dfb88eef..0fa6f0dd 100644 --- a/Assets/Settings/Developer/DebugSettings.asset +++ b/Assets/Settings/Developer/DebugSettings.asset @@ -16,6 +16,7 @@ MonoBehaviour: pauseTimeOnPauseGame: 0 useSaveLoadSystem: 1 autoClearSaves: 0 + dontSaveOnQuit: 0 bootstrapLogVerbosity: 0 settingsLogVerbosity: 0 gameManagerLogVerbosity: 0 From 86c1df55f2e217e1b0e666aae054e412a3cee058 Mon Sep 17 00:00:00 2001 From: tschesky Date: Mon, 24 Nov 2025 14:55:45 +0000 Subject: [PATCH 4/4] First pass over MPV for the cement-statue-sticker minigame (#63) Co-authored-by: Michal Pikulski Co-authored-by: Michal Pikulski Reviewed-on: https://homelab.tailf7f81b.ts.net/tschesky/AppleHillsProduction/pulls/63 --- .../AssetGroups/Settings.asset | 5 + .../AEblerup_Map_Statue.png.meta | 34 +- Assets/Data/Minigames.meta | 8 + .../{ => Minigames}/CardQualityControl.meta | 0 .../ExampleGarbageItem.asset | 0 .../ExampleGarbageItem.asset.meta | 0 Assets/Data/Minigames/StatueDressup.meta | 8 + .../StatueDressup/TestDecorationData 1.asset | 19 + .../TestDecorationData 1.asset.meta | 8 + .../StatueDressup/TestDecorationData 2.asset | 19 + .../TestDecorationData 2.asset.meta | 8 + .../StatueDressup/TestDecorationData 3.asset | 19 + .../TestDecorationData 3.asset.meta | 8 + .../StatueDressup/TestDecorationData 4.asset | 19 + .../TestDecorationData 4.asset.meta | 8 + .../StatueDressup/TestDecorationData 5.asset | 19 + .../TestDecorationData 5.asset.meta | 8 + .../StatueDressup/TestDecorationData 6.asset | 19 + .../TestDecorationData 6.asset.meta | 8 + .../StatueDressup/TestDecorationData 7.asset | 19 + .../TestDecorationData 7.asset.meta | 8 + .../StatueDressup/TestDecorationData 8.asset | 19 + .../TestDecorationData 8.asset.meta | 8 + .../StatueDressup/TestDecorationData 9.asset | 19 + .../TestDecorationData 9.asset.meta | 8 + .../StatueDressup/TestDecorationData.asset | 19 + .../TestDecorationData.asset.meta | 8 + .../Settings/SceneOrientationConfig.asset | 4 +- .../Editor/Settings/SettingsEditorWindow.cs | 7 +- Assets/External/Placeholders/camera_icon.png | Bin 0 -> 3865 bytes .../Placeholders/camera_icon.png.meta | 195 +++ .../External/Placeholders/statue_outline.png | Bin 0 -> 4456 bytes .../Placeholders/statue_outline.png.meta | 195 +++ Assets/Prefabs/Minigames/StatueDressup.meta | 8 + .../DecorationDraggableInstance.prefab | 105 ++ .../DecorationDraggableInstance.prefab.meta | 7 + .../StatueDressup/DecorationGridIcon.prefab | 105 ++ .../DecorationGridIcon.prefab.meta | 7 + .../ApplehillsFont/AppleHills01 SDF.asset | 997 ++++++++---- .../Scenes/MiniGames/StatueDecoration.unity | 1416 +++++++++++++++-- Assets/Scripts/Core/GameManager.cs | 14 +- .../Core/Settings/SettingsInterfaces.cs | 42 + .../Core/Settings/StatueDressupSettings.cs | 149 ++ .../Settings/StatueDressupSettings.cs.meta | 3 + Assets/Scripts/Minigames/StatueDressup.meta | 3 + .../Minigames/StatueDressup/Controllers.meta | 3 + .../Controllers/DecorationMenuController.cs | 333 ++++ .../DecorationMenuController.cs.meta | 3 + .../Controllers/StatueDecorationController.cs | 307 ++++ .../StatueDecorationController.cs.meta | 3 + .../Scripts/Minigames/StatueDressup/Data.meta | 3 + .../StatueDressup/Data/DecorationData.cs | 42 + .../StatueDressup/Data/DecorationData.cs.meta | 3 + .../Minigames/StatueDressup/DragDrop.meta | 3 + .../DragDrop/DecorationDraggableInstance.cs | 242 +++ .../DecorationDraggableInstance.cs.meta | 3 + .../DragDrop/DecorationGridIcon.cs | 100 ++ .../DragDrop/DecorationGridIcon.cs.meta | 3 + .../Minigames/StatueDressup/Utils.meta | 3 + .../Utils/TweenAnimationUtility.cs | 171 ++ .../Utils/TweenAnimationUtility.cs.meta | 3 + Assets/Scripts/UI/PlayerHudManager.cs | 2 +- Assets/Settings/BirdPooperSettings.asset | 2 + Assets/Settings/InteractionSettings.asset | 5 + Assets/Settings/StatueDressupSettings.asset | 44 + .../Settings/StatueDressupSettings.asset.meta | 8 + 66 files changed, 4455 insertions(+), 413 deletions(-) create mode 100644 Assets/Data/Minigames.meta rename Assets/Data/{ => Minigames}/CardQualityControl.meta (100%) rename Assets/Data/{ => Minigames}/CardQualityControl/ExampleGarbageItem.asset (100%) rename Assets/Data/{ => Minigames}/CardQualityControl/ExampleGarbageItem.asset.meta (100%) create mode 100644 Assets/Data/Minigames/StatueDressup.meta create mode 100644 Assets/Data/Minigames/StatueDressup/TestDecorationData 1.asset create mode 100644 Assets/Data/Minigames/StatueDressup/TestDecorationData 1.asset.meta create mode 100644 Assets/Data/Minigames/StatueDressup/TestDecorationData 2.asset create mode 100644 Assets/Data/Minigames/StatueDressup/TestDecorationData 2.asset.meta create mode 100644 Assets/Data/Minigames/StatueDressup/TestDecorationData 3.asset create mode 100644 Assets/Data/Minigames/StatueDressup/TestDecorationData 3.asset.meta create mode 100644 Assets/Data/Minigames/StatueDressup/TestDecorationData 4.asset create mode 100644 Assets/Data/Minigames/StatueDressup/TestDecorationData 4.asset.meta create mode 100644 Assets/Data/Minigames/StatueDressup/TestDecorationData 5.asset create mode 100644 Assets/Data/Minigames/StatueDressup/TestDecorationData 5.asset.meta create mode 100644 Assets/Data/Minigames/StatueDressup/TestDecorationData 6.asset create mode 100644 Assets/Data/Minigames/StatueDressup/TestDecorationData 6.asset.meta create mode 100644 Assets/Data/Minigames/StatueDressup/TestDecorationData 7.asset create mode 100644 Assets/Data/Minigames/StatueDressup/TestDecorationData 7.asset.meta create mode 100644 Assets/Data/Minigames/StatueDressup/TestDecorationData 8.asset create mode 100644 Assets/Data/Minigames/StatueDressup/TestDecorationData 8.asset.meta create mode 100644 Assets/Data/Minigames/StatueDressup/TestDecorationData 9.asset create mode 100644 Assets/Data/Minigames/StatueDressup/TestDecorationData 9.asset.meta create mode 100644 Assets/Data/Minigames/StatueDressup/TestDecorationData.asset create mode 100644 Assets/Data/Minigames/StatueDressup/TestDecorationData.asset.meta create mode 100644 Assets/External/Placeholders/camera_icon.png create mode 100644 Assets/External/Placeholders/camera_icon.png.meta create mode 100644 Assets/External/Placeholders/statue_outline.png create mode 100644 Assets/External/Placeholders/statue_outline.png.meta create mode 100644 Assets/Prefabs/Minigames/StatueDressup.meta create mode 100644 Assets/Prefabs/Minigames/StatueDressup/DecorationDraggableInstance.prefab create mode 100644 Assets/Prefabs/Minigames/StatueDressup/DecorationDraggableInstance.prefab.meta create mode 100644 Assets/Prefabs/Minigames/StatueDressup/DecorationGridIcon.prefab create mode 100644 Assets/Prefabs/Minigames/StatueDressup/DecorationGridIcon.prefab.meta create mode 100644 Assets/Scripts/Core/Settings/StatueDressupSettings.cs create mode 100644 Assets/Scripts/Core/Settings/StatueDressupSettings.cs.meta create mode 100644 Assets/Scripts/Minigames/StatueDressup.meta create mode 100644 Assets/Scripts/Minigames/StatueDressup/Controllers.meta create mode 100644 Assets/Scripts/Minigames/StatueDressup/Controllers/DecorationMenuController.cs create mode 100644 Assets/Scripts/Minigames/StatueDressup/Controllers/DecorationMenuController.cs.meta create mode 100644 Assets/Scripts/Minigames/StatueDressup/Controllers/StatueDecorationController.cs create mode 100644 Assets/Scripts/Minigames/StatueDressup/Controllers/StatueDecorationController.cs.meta create mode 100644 Assets/Scripts/Minigames/StatueDressup/Data.meta create mode 100644 Assets/Scripts/Minigames/StatueDressup/Data/DecorationData.cs create mode 100644 Assets/Scripts/Minigames/StatueDressup/Data/DecorationData.cs.meta create mode 100644 Assets/Scripts/Minigames/StatueDressup/DragDrop.meta create mode 100644 Assets/Scripts/Minigames/StatueDressup/DragDrop/DecorationDraggableInstance.cs create mode 100644 Assets/Scripts/Minigames/StatueDressup/DragDrop/DecorationDraggableInstance.cs.meta create mode 100644 Assets/Scripts/Minigames/StatueDressup/DragDrop/DecorationGridIcon.cs create mode 100644 Assets/Scripts/Minigames/StatueDressup/DragDrop/DecorationGridIcon.cs.meta create mode 100644 Assets/Scripts/Minigames/StatueDressup/Utils.meta create mode 100644 Assets/Scripts/Minigames/StatueDressup/Utils/TweenAnimationUtility.cs create mode 100644 Assets/Scripts/Minigames/StatueDressup/Utils/TweenAnimationUtility.cs.meta create mode 100644 Assets/Settings/StatueDressupSettings.asset create mode 100644 Assets/Settings/StatueDressupSettings.asset.meta diff --git a/Assets/AddressableAssetsData/AssetGroups/Settings.asset b/Assets/AddressableAssetsData/AssetGroups/Settings.asset index 99878cf1..cac13c80 100644 --- a/Assets/AddressableAssetsData/AssetGroups/Settings.asset +++ b/Assets/AddressableAssetsData/AssetGroups/Settings.asset @@ -20,6 +20,11 @@ MonoBehaviour: m_ReadOnly: 0 m_SerializedLabels: [] FlaggedDuringContentUpdateRestriction: 0 + - m_GUID: 359004e51663d6442b7d2b960d12b459 + m_Address: Settings/StatueDressupSettings + m_ReadOnly: 0 + m_SerializedLabels: [] + FlaggedDuringContentUpdateRestriction: 0 - m_GUID: 35bfcff00faa72c4eb272a9e8288f965 m_Address: Settings/PlayerFollowerSettings m_ReadOnly: 0 diff --git a/Assets/Art/Sprites/OverworldBuildings/AEblerup_Map_Statue.png.meta b/Assets/Art/Sprites/OverworldBuildings/AEblerup_Map_Statue.png.meta index 041175fc..f673f5f7 100644 --- a/Assets/Art/Sprites/OverworldBuildings/AEblerup_Map_Statue.png.meta +++ b/Assets/Art/Sprites/OverworldBuildings/AEblerup_Map_Statue.png.meta @@ -122,6 +122,32 @@ TextureImporter: ignorePlatformSupport: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: WindowsStoreApps + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 spriteSheet: serializedVersion: 2 sprites: @@ -129,10 +155,10 @@ TextureImporter: name: AEblerup_Map_Statue_0 rect: serializedVersion: 2 - x: 59 - y: 48 - width: 405 - height: 567 + x: 0 + y: 0 + width: 555 + height: 676 alignment: 9 pivot: {x: 0.5, y: 0.25} border: {x: 0, y: 0, z: 0, w: 0} diff --git a/Assets/Data/Minigames.meta b/Assets/Data/Minigames.meta new file mode 100644 index 00000000..1fedef71 --- /dev/null +++ b/Assets/Data/Minigames.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7091cb36c910f2946b53eb474bb12c0c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/CardQualityControl.meta b/Assets/Data/Minigames/CardQualityControl.meta similarity index 100% rename from Assets/Data/CardQualityControl.meta rename to Assets/Data/Minigames/CardQualityControl.meta diff --git a/Assets/Data/CardQualityControl/ExampleGarbageItem.asset b/Assets/Data/Minigames/CardQualityControl/ExampleGarbageItem.asset similarity index 100% rename from Assets/Data/CardQualityControl/ExampleGarbageItem.asset rename to Assets/Data/Minigames/CardQualityControl/ExampleGarbageItem.asset diff --git a/Assets/Data/CardQualityControl/ExampleGarbageItem.asset.meta b/Assets/Data/Minigames/CardQualityControl/ExampleGarbageItem.asset.meta similarity index 100% rename from Assets/Data/CardQualityControl/ExampleGarbageItem.asset.meta rename to Assets/Data/Minigames/CardQualityControl/ExampleGarbageItem.asset.meta diff --git a/Assets/Data/Minigames/StatueDressup.meta b/Assets/Data/Minigames/StatueDressup.meta new file mode 100644 index 00000000..6fdf3f53 --- /dev/null +++ b/Assets/Data/Minigames/StatueDressup.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 66399ae87653d9b43b7a55fadc15c136 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Minigames/StatueDressup/TestDecorationData 1.asset b/Assets/Data/Minigames/StatueDressup/TestDecorationData 1.asset new file mode 100644 index 00000000..61d245ae --- /dev/null +++ b/Assets/Data/Minigames/StatueDressup/TestDecorationData 1.asset @@ -0,0 +1,19 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 74c6ae9aa803480c8fb918dd58cfb809, type: 3} + m_Name: TestDecorationData 1 + m_EditorClassIdentifier: AppleHillsScripts::Minigames.StatueDressup.Data.DecorationData + decorationId: Shoe + decorationName: Shoe + decorationSprite: {fileID: -792204027, guid: f1b529408513adc409a57c9ba7131823, type: 3} + authoredSize: {x: 300, y: 300} + isUnlocked: 1 diff --git a/Assets/Data/Minigames/StatueDressup/TestDecorationData 1.asset.meta b/Assets/Data/Minigames/StatueDressup/TestDecorationData 1.asset.meta new file mode 100644 index 00000000..0af9305c --- /dev/null +++ b/Assets/Data/Minigames/StatueDressup/TestDecorationData 1.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ca949a6208ce5b5488e90ea3e2eed6df +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Minigames/StatueDressup/TestDecorationData 2.asset b/Assets/Data/Minigames/StatueDressup/TestDecorationData 2.asset new file mode 100644 index 00000000..e6c86cf0 --- /dev/null +++ b/Assets/Data/Minigames/StatueDressup/TestDecorationData 2.asset @@ -0,0 +1,19 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 74c6ae9aa803480c8fb918dd58cfb809, type: 3} + m_Name: TestDecorationData 2 + m_EditorClassIdentifier: AppleHillsScripts::Minigames.StatueDressup.Data.DecorationData + decorationId: axe + decorationName: axe + decorationSprite: {fileID: 6674386295937086461, guid: 3bd1c178a78fcd144965cd1731dc309b, type: 3} + authoredSize: {x: 300, y: 300} + isUnlocked: 1 diff --git a/Assets/Data/Minigames/StatueDressup/TestDecorationData 2.asset.meta b/Assets/Data/Minigames/StatueDressup/TestDecorationData 2.asset.meta new file mode 100644 index 00000000..166bfc4a --- /dev/null +++ b/Assets/Data/Minigames/StatueDressup/TestDecorationData 2.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5efa934e009bc234e920904b05db3c2f +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Minigames/StatueDressup/TestDecorationData 3.asset b/Assets/Data/Minigames/StatueDressup/TestDecorationData 3.asset new file mode 100644 index 00000000..4297c1d6 --- /dev/null +++ b/Assets/Data/Minigames/StatueDressup/TestDecorationData 3.asset @@ -0,0 +1,19 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 74c6ae9aa803480c8fb918dd58cfb809, type: 3} + m_Name: TestDecorationData 3 + m_EditorClassIdentifier: AppleHillsScripts::Minigames.StatueDressup.Data.DecorationData + decorationId: can + decorationName: can + decorationSprite: {fileID: 792078976, guid: f1b529408513adc409a57c9ba7131823, type: 3} + authoredSize: {x: 300, y: 300} + isUnlocked: 1 diff --git a/Assets/Data/Minigames/StatueDressup/TestDecorationData 3.asset.meta b/Assets/Data/Minigames/StatueDressup/TestDecorationData 3.asset.meta new file mode 100644 index 00000000..e02a1bb8 --- /dev/null +++ b/Assets/Data/Minigames/StatueDressup/TestDecorationData 3.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8819ec8b1f4910a4494755cf043636d1 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Minigames/StatueDressup/TestDecorationData 4.asset b/Assets/Data/Minigames/StatueDressup/TestDecorationData 4.asset new file mode 100644 index 00000000..614d5d8f --- /dev/null +++ b/Assets/Data/Minigames/StatueDressup/TestDecorationData 4.asset @@ -0,0 +1,19 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 74c6ae9aa803480c8fb918dd58cfb809, type: 3} + m_Name: TestDecorationData 4 + m_EditorClassIdentifier: AppleHillsScripts::Minigames.StatueDressup.Data.DecorationData + decorationId: i_feel_the_magic_between_you_and_i + decorationName: I feel the magic between you and I + decorationSprite: {fileID: 1623587888, guid: 1630961e1f25e4243ad74e4e3b0c7e54, type: 3} + authoredSize: {x: 300, y: 300} + isUnlocked: 1 diff --git a/Assets/Data/Minigames/StatueDressup/TestDecorationData 4.asset.meta b/Assets/Data/Minigames/StatueDressup/TestDecorationData 4.asset.meta new file mode 100644 index 00000000..ac165bbd --- /dev/null +++ b/Assets/Data/Minigames/StatueDressup/TestDecorationData 4.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b09b79db8ef15144bb2138ec59f26a9c +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Minigames/StatueDressup/TestDecorationData 5.asset b/Assets/Data/Minigames/StatueDressup/TestDecorationData 5.asset new file mode 100644 index 00000000..94caddf2 --- /dev/null +++ b/Assets/Data/Minigames/StatueDressup/TestDecorationData 5.asset @@ -0,0 +1,19 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 74c6ae9aa803480c8fb918dd58cfb809, type: 3} + m_Name: TestDecorationData 5 + m_EditorClassIdentifier: AppleHillsScripts::Minigames.StatueDressup.Data.DecorationData + decorationId: the_people's_sticker + decorationName: the people's sticker + decorationSprite: {fileID: 3452003437791708593, guid: 4c13556eeb918624c9dd3d7e4086242e, type: 3} + authoredSize: {x: 300, y: 300} + isUnlocked: 1 diff --git a/Assets/Data/Minigames/StatueDressup/TestDecorationData 5.asset.meta b/Assets/Data/Minigames/StatueDressup/TestDecorationData 5.asset.meta new file mode 100644 index 00000000..28035228 --- /dev/null +++ b/Assets/Data/Minigames/StatueDressup/TestDecorationData 5.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8838477f768600848813a215ab6a46fe +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Minigames/StatueDressup/TestDecorationData 6.asset b/Assets/Data/Minigames/StatueDressup/TestDecorationData 6.asset new file mode 100644 index 00000000..5983097d --- /dev/null +++ b/Assets/Data/Minigames/StatueDressup/TestDecorationData 6.asset @@ -0,0 +1,19 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 74c6ae9aa803480c8fb918dd58cfb809, type: 3} + m_Name: TestDecorationData 6 + m_EditorClassIdentifier: AppleHillsScripts::Minigames.StatueDressup.Data.DecorationData + decorationId: cardalbum + decorationName: CardAlbum + decorationSprite: {fileID: -4354454609415314374, guid: 1ba1f8cf73f79214190f1432fe1e3bc6, type: 3} + authoredSize: {x: 300, y: 300} + isUnlocked: 1 diff --git a/Assets/Data/Minigames/StatueDressup/TestDecorationData 6.asset.meta b/Assets/Data/Minigames/StatueDressup/TestDecorationData 6.asset.meta new file mode 100644 index 00000000..1b839aeb --- /dev/null +++ b/Assets/Data/Minigames/StatueDressup/TestDecorationData 6.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f0df83df3cff9d84ba9fd4895e5d1b58 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Minigames/StatueDressup/TestDecorationData 7.asset b/Assets/Data/Minigames/StatueDressup/TestDecorationData 7.asset new file mode 100644 index 00000000..124bf5da --- /dev/null +++ b/Assets/Data/Minigames/StatueDressup/TestDecorationData 7.asset @@ -0,0 +1,19 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 74c6ae9aa803480c8fb918dd58cfb809, type: 3} + m_Name: TestDecorationData 7 + m_EditorClassIdentifier: AppleHillsScripts::Minigames.StatueDressup.Data.DecorationData + decorationId: chocolate + decorationName: chocolate + decorationSprite: {fileID: -509776585262497855, guid: c648336c825f7d7479582bbe4d95d0bc, type: 3} + authoredSize: {x: 300, y: 300} + isUnlocked: 1 diff --git a/Assets/Data/Minigames/StatueDressup/TestDecorationData 7.asset.meta b/Assets/Data/Minigames/StatueDressup/TestDecorationData 7.asset.meta new file mode 100644 index 00000000..b07c0a84 --- /dev/null +++ b/Assets/Data/Minigames/StatueDressup/TestDecorationData 7.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4101d48e428899d409df02f24c83571f +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Minigames/StatueDressup/TestDecorationData 8.asset b/Assets/Data/Minigames/StatueDressup/TestDecorationData 8.asset new file mode 100644 index 00000000..90398526 --- /dev/null +++ b/Assets/Data/Minigames/StatueDressup/TestDecorationData 8.asset @@ -0,0 +1,19 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 74c6ae9aa803480c8fb918dd58cfb809, type: 3} + m_Name: TestDecorationData 8 + m_EditorClassIdentifier: AppleHillsScripts::Minigames.StatueDressup.Data.DecorationData + decorationId: tennis_ball + decorationName: tennis ball + decorationSprite: {fileID: -8897872742393391051, guid: 44a64b7a80921694790236bab7765357, type: 3} + authoredSize: {x: 300, y: 300} + isUnlocked: 1 diff --git a/Assets/Data/Minigames/StatueDressup/TestDecorationData 8.asset.meta b/Assets/Data/Minigames/StatueDressup/TestDecorationData 8.asset.meta new file mode 100644 index 00000000..964d9803 --- /dev/null +++ b/Assets/Data/Minigames/StatueDressup/TestDecorationData 8.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b01ee8334ee052b4784225337e9a5ece +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Minigames/StatueDressup/TestDecorationData 9.asset b/Assets/Data/Minigames/StatueDressup/TestDecorationData 9.asset new file mode 100644 index 00000000..7333058a --- /dev/null +++ b/Assets/Data/Minigames/StatueDressup/TestDecorationData 9.asset @@ -0,0 +1,19 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 74c6ae9aa803480c8fb918dd58cfb809, type: 3} + m_Name: TestDecorationData 9 + m_EditorClassIdentifier: AppleHillsScripts::Minigames.StatueDressup.Data.DecorationData + decorationId: bird_poop + decorationName: bird poop + decorationSprite: {fileID: 6130942287420046110, guid: 9ef635f111f888a4386a7f0290117264, type: 3} + authoredSize: {x: 300, y: 300} + isUnlocked: 1 diff --git a/Assets/Data/Minigames/StatueDressup/TestDecorationData 9.asset.meta b/Assets/Data/Minigames/StatueDressup/TestDecorationData 9.asset.meta new file mode 100644 index 00000000..8fe1e527 --- /dev/null +++ b/Assets/Data/Minigames/StatueDressup/TestDecorationData 9.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a5d493c2c7c9cf74cab038023b401273 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Minigames/StatueDressup/TestDecorationData.asset b/Assets/Data/Minigames/StatueDressup/TestDecorationData.asset new file mode 100644 index 00000000..95d89ca9 --- /dev/null +++ b/Assets/Data/Minigames/StatueDressup/TestDecorationData.asset @@ -0,0 +1,19 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 74c6ae9aa803480c8fb918dd58cfb809, type: 3} + m_Name: TestDecorationData + m_EditorClassIdentifier: AppleHillsScripts::Minigames.StatueDressup.Data.DecorationData + decorationId: backpack + decorationName: backpack + decorationSprite: {fileID: -6415490079858998490, guid: b9d1a045f7c163a4d9e2d38071913885, type: 3} + authoredSize: {x: 300, y: 300} + isUnlocked: 1 diff --git a/Assets/Data/Minigames/StatueDressup/TestDecorationData.asset.meta b/Assets/Data/Minigames/StatueDressup/TestDecorationData.asset.meta new file mode 100644 index 00000000..0c66135c --- /dev/null +++ b/Assets/Data/Minigames/StatueDressup/TestDecorationData.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2ea75de9ff6dbfb4b8c246a654868479 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Settings/SceneOrientationConfig.asset b/Assets/Data/Settings/SceneOrientationConfig.asset index 63c20f2b..830b7713 100644 --- a/Assets/Data/Settings/SceneOrientationConfig.asset +++ b/Assets/Data/Settings/SceneOrientationConfig.asset @@ -19,7 +19,9 @@ MonoBehaviour: requiredOrientation: 1 - sceneName: DivingForPictures requiredOrientation: 0 - - sceneName: BirdB + - sceneName: BirdPoop requiredOrientation: 1 - sceneName: CardQualityControl requiredOrientation: 1 + - sceneName: StatueDecoration + requiredOrientation: 1 diff --git a/Assets/Editor/Settings/SettingsEditorWindow.cs b/Assets/Editor/Settings/SettingsEditorWindow.cs index 08cc509d..a17d1804 100644 --- a/Assets/Editor/Settings/SettingsEditorWindow.cs +++ b/Assets/Editor/Settings/SettingsEditorWindow.cs @@ -2,7 +2,6 @@ using UnityEditor; using System.Collections.Generic; using System.Linq; -using System.IO; using Core.Settings; namespace AppleHills.Core.Settings.Editor @@ -11,7 +10,7 @@ namespace AppleHills.Core.Settings.Editor { private Vector2 scrollPosition; private List allSettings = new List(); - private string[] tabNames = new string[] { "Player & Follower", "Interaction & Items", "Diving Minigame", "Card System", "Card Sorting", "Bird Pooper" }; + private string[] tabNames = new string[] { "Player & Follower", "Interaction & Items", "Diving Minigame", "Card System", "Card Sorting", "Bird Pooper", "Statue Dressup" }; private int selectedTab = 0; private Dictionary serializedSettingsObjects = new Dictionary(); private GUIStyle headerStyle; @@ -52,6 +51,7 @@ namespace AppleHills.Core.Settings.Editor CreateSettingsIfMissing("CardSystemSettings"); CreateSettingsIfMissing("CardSortingSettings"); CreateSettingsIfMissing("BirdPooperSettings"); + CreateSettingsIfMissing("StatueDressupSettings"); } private void CreateSettingsIfMissing(string fileName) where T : BaseSettings @@ -127,6 +127,9 @@ namespace AppleHills.Core.Settings.Editor case 5: // Bird Pooper DrawSettingsEditor(); break; + case 6: // Statue Dressup + DrawSettingsEditor(); + break; } EditorGUILayout.EndScrollView(); diff --git a/Assets/External/Placeholders/camera_icon.png b/Assets/External/Placeholders/camera_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..22c2de2cacfd856ca296627cee381a8001833682 GIT binary patch literal 3865 zcmd5;`CC(G7C!gpCS+kJffTHX3pFT(D7DhEg#ZJhBB&LtAW_u82NbFhS%h2`aUEh6 z9Y#Qd9Te(9w05+z-9QyvVZc_AB1*8Lpe#{v$Uscyi}r_^|6r0Q+%+!g47_;cWjK!D3ij$tDm zJqr`UR;>WY`Urq51Tfo^g8=DbfEO}=&r1QEQp;~d`Jxw$P0K=q!DRlb8qOUcz)%^gjuOQuUOfK$W0xdoBiu!_KIbcr zskM3ZE#2$myNFRYb*W`mQu|4&fp9z;n9{z^;rc%9HNyfZc$`j5+Mb-d!~12&4XUBQ z0c=&k235W6Z6%O_3>7d%u?eYtDj+qSuGw31ejvEcoBe-lvsJeKK49t?k?-nHY^Uz4 zFNP+aNk5_pec~+xW+dsTj%)g89oYhvbQ2$#>!wTq@%7cXV57t>CMT9 zuL9VfUKx&S+%3PgGKF+_DoZA(O_vJtJC5^8Pfi{kZVu`F*mAz*-MzGzVOh05i3Du2 zepg_j@l)DYuc*)K`$*r3d@Iv|o2u@J0bL_)=Pw*D-M@E?WQ}1zd@v!k%z@2`w>>>4 zup{RJ=@K1H7+t_7wHA`bA|CYHkoLA~fCzwtk{Ha^2qJ7FU81L{m;?_r=9g=sFaW~; z_a(7ho<4#JQyljEy)hNS{8=%X2qz}9Qv%2uhRUAI8Q6>*(5{vkUdNXa1rRihwb)mD5+O$)fGL63^Q24n<;cIi9zjBRQaR znu6pniK5NvKTZNu0Z;$b%|czS(rlwz$FnBP_hf#LKaMcpK1Lx?GGkOvTS)%ljRD+n zf;t6kZtKCdN)wO{&~Ayk1Ju8*LGqK?7>moUjx~ng|J^4N$o7^!U5eG)fKG`?D`{@m zSfV4^po-Eqjel8!>(70yu+Dff3D-5VJcrvk`J+|J=ifVkxcW@(zD1JxbRZg&sw`Ci z(!RxO7?A*#g52#qj7vVy2T6qb3N~^k8T8=+9c&E;K?G!HG=X|iqnwSJk(tZIB0-}2 zhDqX(F9?ARyGL}hdt-;W%;xxh+B^_Ksxz70!-DQtbG&8637v}FQ_)z`eg5m=TfI9K zwQWgCwEeq`1`+O!b)K~|cw12o{;sv_dE|~IUq{xM8ncz+mO|5|vNv+N?CFZl-7fWA zSU9PRhJ#K3A>>D80d$bq3Fl7m0JwQ-DjHF=aNS5Ykh5kgTbG%pAC5dbqZz%}%mSu< zStghK+N0_pd+l6%0(oOBtjed zf#eUkD#V0PABCK7&AgDa-x=u4)R_5LfW0#?@X!-zY6(dLo|?WrQ2+beSqlsmK*}`R zpps6Zloa(TiB1t9*{}Ts<^ic|%|0OSCuA4KeLW|q8-~Z$M%{nuDo(YRym0`!Ds}%_ z*0pc@`)Wi?MFNdQnAZ|vg@5<@xbvaFs(bp|l6^M7R@|!DfS3E8C>0nTQDUE;A|fAV zp4xt>^ZQ@Rh-QJSYRqqL0vE(jFZ&}^>hW=Esi=5xU^SAJ*}gBt_bzV`D|nzz2xO(M zG>dET_cS)hO$_gF#1({7qXW)#7&an?)d?*pcOrtxM*$*iLOh)EQUv+dLC&c-gnz9I z)m&vo0YoBhsnNbj25NkqbFS4aeYfPMnB7S7oXpjT<6n(au&?7#WJARSHCl#Y=+ImU z${qAwIS=&!E?Lb}_C%W^eq)EH(!=*V>L3yl`RRrL!RStPpG zv=U{FLLh5xNUoc;dJ?1lU6D@Qh@yjr@4Y$|_V z1LTJevhR>*2vwxB6x7YP|k#Ze3M)^`!bdjpun z`&1{iB{bBn4QdghF8Q5**V2}VjzRp4x>`u8tp zR^DwOH(Aq3?}*Q!9H>wHE#Bw!M{1CxpMgM9Qll$e|AU2Fula}w(YBkH%Tj2>P2M|R zWQUIn#8=92R8o`>a-Dc50kk`Z-pop*liT%Y>>}4j0VSgk_-as22#DMn1rqOVMfl0M zg(}qaann6v4`|4;Xfc0QDSNk`*25w2y21WVhZH;Xoce zfI|dE^++)&aOQ4DhoD?i6O54zSBkpz<%`OP0(=!v+M=lT5>3jD6wbPEorV0AfGdnSuu)X`i8MvZu#tyce(F+qkern2 zzX9!5>&BvRQoF?S%dBD}*2rX@B<>D8xl>T$fg1c`#of2L(L|!ll-v~SF%y&A!G^}M zOI5m777(Wh!^2DWYb2w^@%mq{Kuo6ytEHcueS|l))fGt{D|NoD<5aW2oWd5N`^4S= za}qyOuH&aiS?_>7X5aac6FAkBZ)+UQp$o&L;tvRRp4!PM0u{mK^xnNG>Es|wkym0x zeZ6C+=?nY9IxTANb6CGC*58rQ$mUzhF8HB3WyIQC_{=_o02<>;D9+3+2NJXDLT8SD zPqyOnsZbDalx5E)wSDVbv%6Wq*T(pu30%$)>X&K>u#_LXXp=!3hu2V5(Ll1>DmT$w`sI@S2wbAaYUCt}9D zfJ7n$4cTv}{mz1FK7W*Ac!$ye*KYbRhi-I@;NY zLa9*a_OkR%K{?1|S*9oKyf=4tyDURvLn<5&#HxF{dY_8@KRNG6n+%YfH1kjg+++9b zX4GW=EwZ&u(DlNOvO3$iW`fIY|Jz8XGuS4_-Qfs8NB6Ca#vZaR2YdBHsQ8wEQtW~&?I;k z8e}>Ay5KmH6G!7;m$lU54CrzqTU;4rJ(53euQ1+W!(32%l;;R-;b8J%KXfG3y3=vs z%SKcAqbG>dMN09{n06in$PbwK>lz$vjg?K+ z_GqJxaW4;pr-?exOH2^@1jQGk)q2a^KxDgUk>REr4Q{t+oh~r7r+ywVwl)mq^BH`k z9hFkqMO;=rpVs99j4P{TkAVNwBXG|`H3Lc7r=HBmE0K8ppL`l8Evk0kw`tHG`-?fF Nr6Cc)m!z`%{{S-hKx6;_ literal 0 HcmV?d00001 diff --git a/Assets/External/Placeholders/camera_icon.png.meta b/Assets/External/Placeholders/camera_icon.png.meta new file mode 100644 index 00000000..70a617e6 --- /dev/null +++ b/Assets/External/Placeholders/camera_icon.png.meta @@ -0,0 +1,195 @@ +fileFormatVersion: 2 +guid: 77b22fe548c7b264a8c6d243bd1d62ad +TextureImporter: + internalIDToNameTable: + - first: + 213: -6300450527438492720 + second: camera_icon_0 + 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: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 2 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + 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: 0 + swizzle: 50462976 + cookieLightType: 0 + 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: 0 + - 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: 0 + - 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: 0 + - 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: 0 + - serializedVersion: 4 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: WindowsStoreApps + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: + - serializedVersion: 2 + name: camera_icon_0 + rect: + serializedVersion: 2 + x: 19 + y: 68 + width: 474 + height: 377 + alignment: 0 + pivot: {x: 0, y: 0} + border: {x: 0, y: 0, z: 0, w: 0} + customData: + outline: [] + physicsShape: [] + tessellationDetail: -1 + bones: [] + spriteID: 0db2b1360ad4098a0800000000000000 + internalID: -6300450527438492720 + vertices: [] + indices: + edges: [] + weights: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: + camera_icon_0: -6300450527438492720 + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Placeholders/statue_outline.png b/Assets/External/Placeholders/statue_outline.png new file mode 100644 index 0000000000000000000000000000000000000000..1c418172f0457a4bac2bb3831175d74056b109e0 GIT binary patch literal 4456 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 var sortingGameSettings = SettingsProvider.Instance.LoadSettingsSynchronous(); var birdPooperSettings = SettingsProvider.Instance.LoadSettingsSynchronous(); + var statueDressupSettings = SettingsProvider.Instance.LoadSettingsSynchronous(); // Register settings with service locator if (playerSettings != null) @@ -233,9 +234,20 @@ namespace Core { Debug.LogError("Failed to load BirdPooperSettings"); } + + if (statueDressupSettings != null) + { + ServiceLocator.Register(statueDressupSettings); + Logging.Debug("StatueDressupSettings registered successfully"); + } + else + { + Debug.LogError("Failed to load StatueDressupSettings"); + } // Log success - _settingsLoaded = playerSettings != null && interactionSettings != null && minigameSettings != null && cardSystemSettings != null && birdPooperSettings != null; + _settingsLoaded = playerSettings != null && interactionSettings != null && minigameSettings != null + && cardSystemSettings != null && birdPooperSettings != null && statueDressupSettings != null; if (_settingsLoaded) { Logging.Debug("All settings loaded and registered with ServiceLocator"); diff --git a/Assets/Scripts/Core/Settings/SettingsInterfaces.cs b/Assets/Scripts/Core/Settings/SettingsInterfaces.cs index f2017418..4a68006c 100644 --- a/Assets/Scripts/Core/Settings/SettingsInterfaces.cs +++ b/Assets/Scripts/Core/Settings/SettingsInterfaces.cs @@ -1,5 +1,6 @@ using UnityEngine; using System.Collections.Generic; +using Minigames.StatueDressup.Data; namespace AppleHills.Core.Settings { @@ -160,4 +161,45 @@ namespace AppleHills.Core.Settings // General Animation float DefaultAnimationDuration { get; } } + + /// + /// Interface for statue dressup minigame settings + /// + public interface IStatueDressupSettings + { + // Decoration Display + Vector2 DefaultAuthoredSize { get; } + + // Decoration Content + List AllDecorations { get; } + + // Menu Configuration + int ItemsPerPage { get; } + int GridColumns { get; } + Vector2 GridSpacing { get; } + + // Drag and Drop + float DragScaleTransitionDuration { get; } + float ReturnToMenuDuration { get; } + float MinOverlapPercentage { get; } + + // Animation + float HoverScaleMultiplier { get; } + float HoverAnimationDuration { get; } + float PlacementAnimationDuration { get; } + + // Photo Settings + string PhotoSaveKey { get; } + int PhotoQuality { get; } + bool CaptureFullScreen { get; } + + // Rewards + int CardsRewardCount { get; } + bool AutoCompleteOnPhoto { get; } + + // State Persistence + bool EnableStatePersistence { get; } + string StateSaveKey { get; } + int MaxSavedDecorations { get; } + } } diff --git a/Assets/Scripts/Core/Settings/StatueDressupSettings.cs b/Assets/Scripts/Core/Settings/StatueDressupSettings.cs new file mode 100644 index 00000000..1310d21b --- /dev/null +++ b/Assets/Scripts/Core/Settings/StatueDressupSettings.cs @@ -0,0 +1,149 @@ +using System.Collections.Generic; +using AppleHills.Core.Settings; +using Minigames.StatueDressup.Data; +using UnityEngine; + +namespace Core.Settings +{ + /// + /// Settings for the Mr. Cement Statue Decoration minigame + /// + [CreateAssetMenu(fileName = "StatueDressupSettings", menuName = "AppleHills/Settings/Statue Dressup", order = 7)] + public class StatueDressupSettings : BaseSettings, IStatueDressupSettings + { + [Header("Decoration Display")] + [Tooltip("Default full size for decorations when placed on statue")] + [SerializeField] private Vector2 defaultAuthoredSize = new Vector2(128f, 128f); + + [Header("Decoration Content")] + [Tooltip("List of all available decoration data assets")] + [SerializeField] private List allDecorations = new List(); + + [Header("Menu Configuration")] + [Tooltip("Number of decoration items to display per page (2 columns x 5 rows = 10)")] + [SerializeField] private int itemsPerPage = 10; + + [Tooltip("Number of columns in the decoration grid")] + [SerializeField] private int gridColumns = 2; + + [Tooltip("Spacing between grid items")] + [SerializeField] private Vector2 gridSpacing = new Vector2(10f, 10f); + + [Header("Drag and Drop")] + [Tooltip("Duration for icon to full size transition when dragging starts")] + [SerializeField] private float dragScaleTransitionDuration = 0.2f; + + [Tooltip("Duration for return to menu animation")] + [SerializeField] private float returnToMenuDuration = 0.3f; + + [Tooltip("Minimum overlap percentage required to place on statue (0-1)")] + [SerializeField] private float minOverlapPercentage = 0.1f; + + [Header("Animation")] + [Tooltip("Scale multiplier for hover effect (1.0 = no change, 1.1 = 10% larger)")] + [SerializeField] private float hoverScaleMultiplier = 1.05f; + + [Tooltip("Duration of hover animation")] + [SerializeField] private float hoverAnimationDuration = 0.2f; + + [Tooltip("Duration for placement animation")] + [SerializeField] private float placementAnimationDuration = 0.15f; + + [Header("Photo Settings")] + [Tooltip("PlayerPrefs key for saving the statue photo")] + [SerializeField] private string photoSaveKey = "MrCementStatuePhoto"; + + [Tooltip("Quality of the captured photo (1-100)")] + [SerializeField] private int photoQuality = 85; + + [Tooltip("Whether to capture full screen or just statue area")] + [SerializeField] private bool captureFullScreen; + + [Header("Rewards")] + [Tooltip("Number of Blokkemon cards awarded on completion")] + [SerializeField] private int cardsRewardCount = 3; + + [Tooltip("Whether completion is automatic or requires confirmation")] + [SerializeField] private bool autoCompleteOnPhoto = true; + + [Header("State Persistence")] + [Tooltip("Whether to save decoration positions between sessions")] + [SerializeField] private bool enableStatePersistence = true; + + [Tooltip("PlayerPrefs key for saving decoration state")] + [SerializeField] private string stateSaveKey = "StatueDecorationState"; + + [Tooltip("Maximum number of decorations to save")] + [SerializeField] private int maxSavedDecorations = 50; + + // IStatueDressupSettings implementation - Decoration Display + public Vector2 DefaultAuthoredSize => defaultAuthoredSize; + + // IStatueDressupSettings implementation - Decoration Content + public List AllDecorations => allDecorations; + + // IStatueDressupSettings implementation - Menu Configuration + public int ItemsPerPage => itemsPerPage; + public int GridColumns => gridColumns; + public Vector2 GridSpacing => gridSpacing; + + // IStatueDressupSettings implementation - Drag and Drop + public float DragScaleTransitionDuration => dragScaleTransitionDuration; + public float ReturnToMenuDuration => returnToMenuDuration; + public float MinOverlapPercentage => minOverlapPercentage; + + // IStatueDressupSettings implementation - Animation + public float HoverScaleMultiplier => hoverScaleMultiplier; + public float HoverAnimationDuration => hoverAnimationDuration; + public float PlacementAnimationDuration => placementAnimationDuration; + + // IStatueDressupSettings implementation - Photo Settings + public string PhotoSaveKey => photoSaveKey; + public int PhotoQuality => photoQuality; + public bool CaptureFullScreen => captureFullScreen; + + // IStatueDressupSettings implementation - Rewards + public int CardsRewardCount => cardsRewardCount; + public bool AutoCompleteOnPhoto => autoCompleteOnPhoto; + + // IStatueDressupSettings implementation - State Persistence + public bool EnableStatePersistence => enableStatePersistence; + public string StateSaveKey => stateSaveKey; + public int MaxSavedDecorations => maxSavedDecorations; + + public override void OnValidate() + { + base.OnValidate(); + + // Validate decoration display + defaultAuthoredSize.x = Mathf.Max(32f, defaultAuthoredSize.x); + defaultAuthoredSize.y = Mathf.Max(32f, defaultAuthoredSize.y); + + // Validate menu configuration + itemsPerPage = Mathf.Max(1, itemsPerPage); + gridColumns = Mathf.Max(1, gridColumns); + gridSpacing.x = Mathf.Max(0f, gridSpacing.x); + gridSpacing.y = Mathf.Max(0f, gridSpacing.y); + + // Validate drag and drop + dragScaleTransitionDuration = Mathf.Max(0.01f, dragScaleTransitionDuration); + returnToMenuDuration = Mathf.Max(0.01f, returnToMenuDuration); + minOverlapPercentage = Mathf.Clamp01(minOverlapPercentage); + + // Validate animation + hoverScaleMultiplier = Mathf.Max(1f, hoverScaleMultiplier); + hoverAnimationDuration = Mathf.Max(0.01f, hoverAnimationDuration); + placementAnimationDuration = Mathf.Max(0.01f, placementAnimationDuration); + + // Validate photo settings + photoQuality = Mathf.Clamp(photoQuality, 1, 100); + + // Validate rewards + cardsRewardCount = Mathf.Max(0, cardsRewardCount); + + // Validate state persistence + maxSavedDecorations = Mathf.Max(1, maxSavedDecorations); + } + } +} + diff --git a/Assets/Scripts/Core/Settings/StatueDressupSettings.cs.meta b/Assets/Scripts/Core/Settings/StatueDressupSettings.cs.meta new file mode 100644 index 00000000..b08ae026 --- /dev/null +++ b/Assets/Scripts/Core/Settings/StatueDressupSettings.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4fcf232a64e34f489b874519cc96339e +timeCreated: 1763984221 \ No newline at end of file diff --git a/Assets/Scripts/Minigames/StatueDressup.meta b/Assets/Scripts/Minigames/StatueDressup.meta new file mode 100644 index 00000000..b49e5e83 --- /dev/null +++ b/Assets/Scripts/Minigames/StatueDressup.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5596931aef9448a3b369f7917af07797 +timeCreated: 1763745490 \ No newline at end of file diff --git a/Assets/Scripts/Minigames/StatueDressup/Controllers.meta b/Assets/Scripts/Minigames/StatueDressup/Controllers.meta new file mode 100644 index 00000000..8be21da5 --- /dev/null +++ b/Assets/Scripts/Minigames/StatueDressup/Controllers.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 34525368248b48e0b271537891123818 +timeCreated: 1763745579 \ No newline at end of file diff --git a/Assets/Scripts/Minigames/StatueDressup/Controllers/DecorationMenuController.cs b/Assets/Scripts/Minigames/StatueDressup/Controllers/DecorationMenuController.cs new file mode 100644 index 00000000..df8285a5 --- /dev/null +++ b/Assets/Scripts/Minigames/StatueDressup/Controllers/DecorationMenuController.cs @@ -0,0 +1,333 @@ +using System.Collections.Generic; +using Core; +using Core.Lifecycle; +using Minigames.StatueDressup.Data; +using Minigames.StatueDressup.DragDrop; +using UnityEngine; +using UnityEngine.UI; + +namespace Minigames.StatueDressup.Controllers +{ + /// + /// Manages the side menu with decoration items and pagination + /// + public class DecorationMenuController : ManagedBehaviour + { + [Header("References")] + [SerializeField] private DecorationGridIcon iconPrefab; + [SerializeField] private DecorationDraggableInstance draggablePrefab; + [SerializeField] private Transform itemsContainer; + [SerializeField] private Transform draggableContainer; // Parent for spawned draggables + [SerializeField] private Button nextPageButton; + [SerializeField] private Button previousPageButton; + [SerializeField] private StatueDecorationController statueController; // Controller for registration + [SerializeField] private Image statueOutline; // Outline image shown during drag to indicate valid drop area + + [Header("Layout")] + [SerializeField] private GridLayoutGroup gridLayout; + + private int _currentPage; + private int _totalPages; + private List _spawnedIcons = new List(); + private AppleHills.Core.Settings.IStatueDressupSettings _settings; + + // Properties + public int CurrentPage => _currentPage; + public int TotalPages => _totalPages; + + /// + /// Early initialization - get settings reference + /// + internal override void OnManagedAwake() + { + base.OnManagedAwake(); + + // Get settings early + _settings = GameManager.GetSettingsObject(); + + if (_settings == null) + { + Logging.Error("[DecorationMenuController] Failed to load StatueDressupSettings!"); + } + } + + /// + /// Main initialization after all managers are ready + /// + internal override void OnManagedStart() + { + base.OnManagedStart(); + + if (_settings == null) + { + Logging.Error("[DecorationMenuController] Cannot initialize without settings!"); + return; + } + + // Ensure outline starts hidden + if (statueOutline != null) + { + statueOutline.gameObject.SetActive(false); + } + + var allDecorations = _settings.AllDecorations; + int itemsPerPage = _settings.ItemsPerPage; + + Logging.Debug($"[DecorationMenuController] Initializing with {allDecorations?.Count ?? 0} decorations"); + + // Calculate total pages + if (allDecorations != null && allDecorations.Count > 0) + { + _totalPages = Mathf.CeilToInt((float)allDecorations.Count / itemsPerPage); + Logging.Debug($"[DecorationMenuController] Total pages: {_totalPages}"); + } + else + { + Logging.Warning("[DecorationMenuController] No decorations found in settings!"); + _totalPages = 0; + } + + // Setup buttons + if (nextPageButton != null) + { + nextPageButton.onClick.AddListener(OnNextPage); + } + + if (previousPageButton != null) + { + previousPageButton.onClick.AddListener(OnPreviousPage); + } + + // Subscribe to drag events for all items + // (will be handled per-item when spawned) + + // Populate first page + PopulateCurrentPage(); + } + + /// + /// Populate the current page with decoration icons + /// + private void PopulateCurrentPage() + { + if (_settings == null) return; + + var allDecorations = _settings.AllDecorations; + int itemsPerPage = _settings.ItemsPerPage; + + if (allDecorations == null || allDecorations.Count == 0) + { + Logging.Warning("[DecorationMenuController] No decorations to populate"); + return; + } + + Logging.Debug($"[DecorationMenuController] Populating page {_currentPage + 1}/{_totalPages}"); + + // Clear existing icons + ClearIcons(); + + // Calculate range for current page + int startIndex = _currentPage * itemsPerPage; + int endIndex = Mathf.Min(startIndex + itemsPerPage, allDecorations.Count); + + Logging.Debug($"[DecorationMenuController] Spawning icons {startIndex} to {endIndex - 1}"); + + // Spawn icons for this page + for (int i = startIndex; i < endIndex; i++) + { + SpawnGridIcon(allDecorations[i]); + } + + // Update button states + UpdateNavigationButtons(); + } + + /// + /// Spawn a grid icon in the menu + /// + private void SpawnGridIcon(DecorationData data) + { + if (iconPrefab == null || itemsContainer == null) + { + Logging.Warning("[DecorationMenuController] Missing icon prefab or container"); + return; + } + + DecorationGridIcon icon = Instantiate(iconPrefab, itemsContainer); + icon.Initialize(data, this); + + _spawnedIcons.Add(icon); + + Logging.Debug($"[DecorationMenuController] Spawned icon: {data.DecorationName}"); + } + + /// + /// Factory method: Spawn a draggable instance at cursor position + /// Called by DecorationGridIcon when drag starts + /// + public DecorationDraggableInstance SpawnDraggableInstance(DecorationData data, Vector3 screenPosition) + { + if (draggablePrefab == null || statueController == null) + { + Logging.Warning("[DecorationMenuController] Missing draggable prefab or statue controller"); + return null; + } + + // Show statue outline + ShowStatueOutline(); + + // Determine parent - use draggableContainer if set, otherwise itemsContainer's parent + Transform parent = draggableContainer != null ? draggableContainer : itemsContainer.parent; + + // Spawn draggable instance + DecorationDraggableInstance instance = Instantiate(draggablePrefab, parent); + + // Get outline RectTransform for overlap detection + RectTransform outlineRect = statueOutline != null ? statueOutline.rectTransform : null; + + // Initialize with references + instance.Initialize( + data, + outlineRect, + statueController.StatueParent, + statueController, + _settings, + OnDraggableFinished + ); + + // Position at cursor (in local space) + Canvas canvas = GetComponentInParent(); + if (canvas != null) + { + RectTransformUtility.ScreenPointToLocalPointInRectangle( + canvas.transform as RectTransform, + screenPosition, + canvas.worldCamera, + out Vector2 localPoint); + + RectTransform instanceRect = instance.GetComponent(); + if (instanceRect != null) + { + instanceRect.localPosition = localPoint; + } + } + + Logging.Debug($"[DecorationMenuController] Spawned draggable instance: {data.DecorationName}"); + + return instance; + } + + /// + /// Show the statue outline to indicate valid drop area + /// + private void ShowStatueOutline() + { + if (statueOutline != null) + { + statueOutline.gameObject.SetActive(true); + Logging.Debug("[DecorationMenuController] Statue outline shown"); + } + } + + /// + /// Hide the statue outline after drag ends + /// + private void HideStatueOutline() + { + if (statueOutline != null) + { + statueOutline.gameObject.SetActive(false); + Logging.Debug("[DecorationMenuController] Statue outline hidden"); + } + } + + /// + /// Callback from DecorationDraggableInstance when drag finishes + /// + private void OnDraggableFinished() + { + HideStatueOutline(); + } + + /// + /// Clear all spawned icons + /// + private void ClearIcons() + { + foreach (var icon in _spawnedIcons) + { + if (icon != null) + { + Destroy(icon.gameObject); + } + } + + _spawnedIcons.Clear(); + } + + /// + /// Navigate to next page + /// + private void OnNextPage() + { + if (_currentPage < _totalPages - 1) + { + _currentPage++; + PopulateCurrentPage(); + Logging.Debug($"[DecorationMenuController] Next page: {_currentPage + 1}/{_totalPages}"); + } + } + + /// + /// Navigate to previous page + /// + private void OnPreviousPage() + { + if (_currentPage > 0) + { + _currentPage--; + PopulateCurrentPage(); + Logging.Debug($"[DecorationMenuController] Previous page: {_currentPage + 1}/{_totalPages}"); + } + } + + /// + /// Update navigation button interactability + /// + private void UpdateNavigationButtons() + { + if (previousPageButton != null) + { + previousPageButton.interactable = _currentPage > 0; + } + + if (nextPageButton != null) + { + nextPageButton.interactable = _currentPage < _totalPages - 1; + } + } + + /// + /// Cleanup when menu controller is destroyed + /// + internal override void OnManagedDestroy() + { + base.OnManagedDestroy(); + + // Cleanup button listeners + if (nextPageButton != null) + { + nextPageButton.onClick.RemoveListener(OnNextPage); + } + + if (previousPageButton != null) + { + previousPageButton.onClick.RemoveListener(OnPreviousPage); + } + + // Cleanup icons + ClearIcons(); + } + } +} + diff --git a/Assets/Scripts/Minigames/StatueDressup/Controllers/DecorationMenuController.cs.meta b/Assets/Scripts/Minigames/StatueDressup/Controllers/DecorationMenuController.cs.meta new file mode 100644 index 00000000..ca0559ed --- /dev/null +++ b/Assets/Scripts/Minigames/StatueDressup/Controllers/DecorationMenuController.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: acbd542762b44e719326dff6c3a69e6e +timeCreated: 1763745579 \ No newline at end of file diff --git a/Assets/Scripts/Minigames/StatueDressup/Controllers/StatueDecorationController.cs b/Assets/Scripts/Minigames/StatueDressup/Controllers/StatueDecorationController.cs new file mode 100644 index 00000000..abd31db8 --- /dev/null +++ b/Assets/Scripts/Minigames/StatueDressup/Controllers/StatueDecorationController.cs @@ -0,0 +1,307 @@ +using System.Collections.Generic; +using Core; +using Core.Lifecycle; +using Minigames.StatueDressup.DragDrop; +using UnityEngine; +using UnityEngine.UI; + +namespace Minigames.StatueDressup.Controllers +{ + /// + /// Main controller for the Mr. Cement statue decoration minigame + /// Uses overlap-based placement instead of slots + /// + public class StatueDecorationController : ManagedBehaviour + { + [Header("References")] + [SerializeField] private RectTransform statueArea; // Statue area for overlap detection + [SerializeField] private Transform statueParent; // Parent for placed decorations + [SerializeField] private DecorationMenuController menuController; + [SerializeField] private Button takePhotoButton; + [SerializeField] private GameObject statue; + + [Header("UI Elements to Hide for Photo")] + [SerializeField] private GameObject[] uiElementsToHideForPhoto; + + [Header("Photo Settings")] + [SerializeField] private RectTransform photoArea; // Area to capture + [SerializeField] private string photoSaveKey = "MrCementStatuePhoto"; + + private List _placedDecorations = new List(); + private bool _minigameCompleted; + private AppleHills.Core.Settings.IStatueDressupSettings _settings; + + // Public property for menu controller + public Transform StatueParent => statueParent; + + /// + /// Early initialization - get settings reference + /// + internal override void OnManagedAwake() + { + base.OnManagedAwake(); + + // Get settings early + _settings = GameManager.GetSettingsObject(); + } + + /// + /// Main initialization after all managers are ready + /// + internal override void OnManagedStart() + { + base.OnManagedStart(); + + Logging.Debug("[StatueDecorationController] Initializing minigame"); + + // Setup photo button + if (takePhotoButton != null) + { + takePhotoButton.onClick.AddListener(OnTakePhoto); + } + + // Subscribe to menu controller for tracking placed items + // Items will manage their own placement via overlap detection + if (menuController != null) + { + // Menu controller will handle spawning replacements + Logging.Debug("[StatueDecorationController] Menu controller connected"); + } + + // Load saved state if exists + LoadStatueState(); + } + + /// + /// Register a decoration as placed on statue + /// + public void RegisterDecoration(DecorationDraggableInstance decoration) + { + if (decoration != null && !_placedDecorations.Contains(decoration)) + { + _placedDecorations.Add(decoration); + Logging.Debug($"[StatueDecorationController] Decoration placed: {decoration.Data?.DecorationName}"); + + // Auto-save state + SaveStatueState(); + } + } + + /// + /// Unregister a decoration (when removed) + /// + public void UnregisterDecoration(DecorationDraggableInstance decoration) + { + if (decoration != null && _placedDecorations.Contains(decoration)) + { + _placedDecorations.Remove(decoration); + Logging.Debug($"[StatueDecorationController] Decoration removed: {decoration.Data?.DecorationName}"); + + // Auto-save state + SaveStatueState(); + } + } + + /// + /// Take photo of decorated statue + /// + private void OnTakePhoto() + { + if (_minigameCompleted) + { + Logging.Debug("[StatueDecorationController] Minigame already completed"); + return; + } + + Logging.Debug("[StatueDecorationController] Taking photo of statue"); + + // Hide UI elements + HideUIForPhoto(true); + + // Wait a frame for UI to hide, then capture + StartCoroutine(CapturePhotoCoroutine()); + } + + /// + /// Capture photo after UI is hidden + /// + private System.Collections.IEnumerator CapturePhotoCoroutine() + { + yield return new WaitForEndOfFrame(); + + // Capture the photo area + Texture2D photo = CaptureScreenshotArea(); + + if (photo != null) + { + // Save photo to album + SavePhotoToAlbum(photo); + + // Award cards + AwardCards(); + + // Update town icon + UpdateTownIcon(photo); + + // Show completion feedback + ShowCompletionFeedback(); + + _minigameCompleted = true; + } + + // Restore UI + HideUIForPhoto(false); + } + + /// + /// Capture screenshot of specific area + /// + private Texture2D CaptureScreenshotArea() + { + if (photoArea == null) + { + Logging.Warning("[StatueDecorationController] No photo area specified, capturing full screen"); + + // Capture full screen + Texture2D screenshot = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false); + screenshot.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0); + screenshot.Apply(); + return screenshot; + } + + // Get world corners of the rect + Vector3[] corners = new Vector3[4]; + photoArea.GetWorldCorners(corners); + + // Convert to screen space + Vector2 min = RectTransformUtility.WorldToScreenPoint(Camera.main, corners[0]); + Vector2 max = RectTransformUtility.WorldToScreenPoint(Camera.main, corners[2]); + + int width = (int)(max.x - min.x); + int height = (int)(max.y - min.y); + + Logging.Debug($"[StatueDecorationController] Capturing area: {width}x{height} at ({min.x}, {min.y})"); + + // Capture the specified area + Texture2D areaScreenshot = new Texture2D(width, height, TextureFormat.RGB24, false); + areaScreenshot.ReadPixels(new Rect(min.x, min.y, width, height), 0, 0); + areaScreenshot.Apply(); + + return areaScreenshot; + } + + /// + /// Save photo to card album + /// + private void SavePhotoToAlbum(Texture2D photo) + { + // TODO: Integrate with existing album save system + // For now, save to PlayerPrefs as base64 + byte[] bytes = photo.EncodeToPNG(); + string base64 = System.Convert.ToBase64String(bytes); + string saveKey = _settings?.PhotoSaveKey ?? photoSaveKey; + PlayerPrefs.SetString(saveKey, base64); + PlayerPrefs.Save(); + + Logging.Debug("[StatueDecorationController] Photo saved to album"); + } + + /// + /// Award Blokkemon cards to player + /// + private void AwardCards() + { + // TODO: Integrate with MinigameBoosterGiver + // MinigameBoosterGiver.GiveBooster(); + + Logging.Debug("[StatueDecorationController] Cards awarded (TODO: implement)"); + } + + /// + /// Update town menu icon with decorated statue + /// + private void UpdateTownIcon(Texture2D photo) + { + // TODO: Integrate with town system + // TownIconUpdater.SetStatueIcon(photo); + + Logging.Debug("[StatueDecorationController] Town icon updated (TODO: implement)"); + } + + /// + /// Show completion feedback to player + /// + private void ShowCompletionFeedback() + { + // TODO: Show success message/animation + DebugUIMessage.Show("Photo captured! Mr. Cement looks amazing!", Color.green); + Logging.Debug("[StatueDecorationController] Minigame completed!"); + } + + /// + /// Hide/show UI elements for photo + /// + private void HideUIForPhoto(bool hide) + { + foreach (var element in uiElementsToHideForPhoto) + { + if (element != null) + { + element.SetActive(!hide); + } + } + } + + /// + /// Save current statue decoration state + /// + private void SaveStatueState() + { + // Check if persistence is enabled + if (_settings == null || !_settings.EnableStatePersistence) + { + Logging.Debug("[StatueDecorationController] State persistence disabled"); + return; + } + + // TODO: Implement save system + // Save decoration ID + position + rotation for each placed item + // Respect MaxSavedDecorations limit + + Logging.Debug($"[StatueDecorationController] State saved to {_settings.StateSaveKey} (TODO: implement persistence)"); + } + + /// + /// Load saved statue decoration state + /// + private void LoadStatueState() + { + // Check if persistence is enabled + if (_settings == null || !_settings.EnableStatePersistence) + { + Logging.Debug("[StatueDecorationController] State persistence disabled"); + return; + } + + // TODO: Implement load system + // Restore decorations from saved state + + Logging.Debug($"[StatueDecorationController] State loaded from {_settings.StateSaveKey} (TODO: implement persistence)"); + } + + /// + /// Cleanup when controller is destroyed + /// + internal override void OnManagedDestroy() + { + base.OnManagedDestroy(); + + // Cleanup button listener + if (takePhotoButton != null) + { + takePhotoButton.onClick.RemoveListener(OnTakePhoto); + } + } + } +} + diff --git a/Assets/Scripts/Minigames/StatueDressup/Controllers/StatueDecorationController.cs.meta b/Assets/Scripts/Minigames/StatueDressup/Controllers/StatueDecorationController.cs.meta new file mode 100644 index 00000000..c1825a4c --- /dev/null +++ b/Assets/Scripts/Minigames/StatueDressup/Controllers/StatueDecorationController.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 19e312ceaffa40ae90ac87b8209319cb +timeCreated: 1763745610 \ No newline at end of file diff --git a/Assets/Scripts/Minigames/StatueDressup/Data.meta b/Assets/Scripts/Minigames/StatueDressup/Data.meta new file mode 100644 index 00000000..0f1b7a6a --- /dev/null +++ b/Assets/Scripts/Minigames/StatueDressup/Data.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a6e7dfb0a39c441fb8ac888a5e58a91e +timeCreated: 1763745500 \ No newline at end of file diff --git a/Assets/Scripts/Minigames/StatueDressup/Data/DecorationData.cs b/Assets/Scripts/Minigames/StatueDressup/Data/DecorationData.cs new file mode 100644 index 00000000..1177cffc --- /dev/null +++ b/Assets/Scripts/Minigames/StatueDressup/Data/DecorationData.cs @@ -0,0 +1,42 @@ +using UnityEngine; + +namespace Minigames.StatueDressup.Data +{ + /// + /// ScriptableObject data definition for statue decorations + /// + [CreateAssetMenu(fileName = "DecorationData", menuName = "AppleHills/Minigames/Decoration Data", order = 1)] + public class DecorationData : ScriptableObject + { + [Header("Identity")] + [SerializeField] private string decorationId; + [SerializeField] private string decorationName; + + [Header("Visual")] + [SerializeField] private Sprite decorationSprite; + + [Header("Size Configuration")] + [Tooltip("Full size when placed on statue (actual sprite size)")] + [SerializeField] private Vector2 authoredSize = new Vector2(128f, 128f); + + [Header("Progression (Optional)")] + [SerializeField] private bool isUnlocked = true; + + // Properties + public string DecorationId => decorationId; + public string DecorationName => decorationName; + public Sprite DecorationSprite => decorationSprite; + public Vector2 AuthoredSize => authoredSize; + public bool IsUnlocked => isUnlocked; + + private void OnValidate() + { + // Auto-generate ID from name if empty + if (string.IsNullOrEmpty(decorationId) && !string.IsNullOrEmpty(decorationName)) + { + decorationId = decorationName.Replace(" ", "_").ToLower(); + } + } + } +} + diff --git a/Assets/Scripts/Minigames/StatueDressup/Data/DecorationData.cs.meta b/Assets/Scripts/Minigames/StatueDressup/Data/DecorationData.cs.meta new file mode 100644 index 00000000..6d39d0c2 --- /dev/null +++ b/Assets/Scripts/Minigames/StatueDressup/Data/DecorationData.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 74c6ae9aa803480c8fb918dd58cfb809 +timeCreated: 1763745511 \ No newline at end of file diff --git a/Assets/Scripts/Minigames/StatueDressup/DragDrop.meta b/Assets/Scripts/Minigames/StatueDressup/DragDrop.meta new file mode 100644 index 00000000..edc5fcc4 --- /dev/null +++ b/Assets/Scripts/Minigames/StatueDressup/DragDrop.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4c3389a935534b7b86800516ffa42acb +timeCreated: 1763745531 \ No newline at end of file diff --git a/Assets/Scripts/Minigames/StatueDressup/DragDrop/DecorationDraggableInstance.cs b/Assets/Scripts/Minigames/StatueDressup/DragDrop/DecorationDraggableInstance.cs new file mode 100644 index 00000000..e4f2f0fb --- /dev/null +++ b/Assets/Scripts/Minigames/StatueDressup/DragDrop/DecorationDraggableInstance.cs @@ -0,0 +1,242 @@ +using Core; +using Minigames.StatueDressup.Controllers; +using Minigames.StatueDressup.Data; +using Minigames.StatueDressup.Utils; +using UnityEngine; +using UnityEngine.EventSystems; +using UnityEngine.UI; + +namespace Minigames.StatueDressup.DragDrop +{ + /// + /// Draggable instance of a decoration that can be placed on the statue. + /// Created dynamically when dragging from menu or picking up from statue. + /// Destroyed if dropped outside statue area. + /// + public class DecorationDraggableInstance : MonoBehaviour + { + [Header("References")] + [SerializeField] private Image decorationImage; + [SerializeField] private CanvasGroup canvasGroup; + + private DecorationData _decorationData; + private RectTransform _rectTransform; + private Canvas _canvas; + private RectTransform _statueOutline; + private Transform _statueParent; + private StatueDecorationController _controller; + private AppleHills.Core.Settings.IStatueDressupSettings _settings; + private System.Action _onFinishedCallback; + + private bool _isDragging; + private bool _isPlacedOnStatue; + private Vector3 _dragOffset; + + // Properties + public DecorationData Data => _decorationData; + public bool IsPlacedOnStatue => _isPlacedOnStatue; + + private void Awake() + { + _rectTransform = GetComponent(); + _canvas = GetComponentInParent(); + + if (canvasGroup == null) + { + canvasGroup = gameObject.AddComponent(); + } + } + + /// + /// Initialize the draggable instance + /// + public void Initialize(DecorationData data, RectTransform statueOutline, Transform statueParent, + StatueDecorationController controller, AppleHills.Core.Settings.IStatueDressupSettings settings, + System.Action onFinishedCallback) + { + _decorationData = data; + _statueOutline = statueOutline; + _statueParent = statueParent; + _controller = controller; + _settings = settings; + _onFinishedCallback = onFinishedCallback; + + // Set sprite + if (decorationImage != null && data != null && data.DecorationSprite != null) + { + decorationImage.sprite = data.DecorationSprite; + } + + // Set authored size + if (_rectTransform != null && data != null) + { + _rectTransform.sizeDelta = data.AuthoredSize; + } + + Logging.Debug($"[DecorationDraggableInstance] Initialized: {data?.DecorationName}"); + } + + /// + /// Start dragging from icon + /// + public void StartDragFromIcon(PointerEventData eventData) + { + _isDragging = true; + + // Calculate offset from cursor to object center + RectTransformUtility.ScreenPointToLocalPointInRectangle( + _canvas.transform as RectTransform, + eventData.position, + eventData.pressEventCamera, + out Vector2 localPoint); + + _dragOffset = _rectTransform.localPosition - (Vector3)localPoint; + + Logging.Debug($"[DecorationDraggableInstance] Started drag from icon: {_decorationData?.DecorationName}"); + } + + /// + /// Continue dragging + /// + public void ContinueDrag(PointerEventData eventData) + { + if (!_isDragging) return; + + // Update position to follow cursor + RectTransformUtility.ScreenPointToLocalPointInRectangle( + _canvas.transform as RectTransform, + eventData.position, + eventData.pressEventCamera, + out Vector2 localPoint); + + _rectTransform.localPosition = localPoint + (Vector2)_dragOffset; + } + + /// + /// End drag - check placement + /// + public void EndDrag(PointerEventData eventData) + { + _isDragging = false; + + Logging.Debug($"[DecorationDraggableInstance] Drag ended: {_decorationData?.DecorationName}"); + + // Check if overlapping with statue + if (IsOverlappingStatue()) + { + PlaceOnStatue(); + } + else + { + PlayPopOutAndDestroy(); + } + } + + /// + /// Check if item overlaps with statue outline + /// + private bool IsOverlappingStatue() + { + if (_statueOutline == null || _rectTransform == null) + { + Logging.Warning($"[DecorationDraggableInstance] Cannot check overlap - statueOutline or RectTransform is null"); + return false; + } + + // Get bounds of this item in world space + Rect itemRect = GetWorldRect(_rectTransform); + Rect outlineRect = GetWorldRect(_statueOutline); + + // Check for any overlap + bool overlaps = itemRect.Overlaps(outlineRect); + + Logging.Debug($"[DecorationDraggableInstance] Overlap check: {_decorationData?.DecorationName}, overlaps={overlaps}"); + + return overlaps; + } + + /// + /// Get world space rect for a RectTransform + /// + private Rect GetWorldRect(RectTransform rectTransform) + { + Vector3[] corners = new Vector3[4]; + rectTransform.GetWorldCorners(corners); + + Vector3 bottomLeft = corners[0]; + Vector3 topRight = corners[2]; + + return new Rect(bottomLeft.x, bottomLeft.y, topRight.x - bottomLeft.x, topRight.y - bottomLeft.y); + } + + /// + /// Place item on statue at current position + /// + private void PlaceOnStatue() + { + Logging.Debug($"[DecorationDraggableInstance] Placing on statue: {_decorationData?.DecorationName}"); + + _isPlacedOnStatue = true; + + // Move to statue parent if specified + if (_statueParent != null && transform.parent != _statueParent) + { + transform.SetParent(_statueParent, true); // Keep world position + } + + // Register with controller + if (_controller != null) + { + _controller.RegisterDecoration(this); + } + + // Notify menu controller to hide outline + _onFinishedCallback?.Invoke(); + } + + /// + /// Play pop-out animation and destroy + /// + private void PlayPopOutAndDestroy() + { + Logging.Debug($"[DecorationDraggableInstance] Pop-out and destroy: {_decorationData?.DecorationName}"); + + // Notify menu controller to hide outline immediately + _onFinishedCallback?.Invoke(); + + float duration = _settings?.PlacementAnimationDuration ?? 0.3f; + + // Play pop-out with fade animation + TweenAnimationUtility.PopOutWithFade(transform, canvasGroup, duration, () => + { + Destroy(gameObject); + }); + } + + /// + /// Allow picking up from statue for repositioning + /// + public void StartDragFromStatue(Vector3 pointerPosition) + { + if (_controller != null) + { + _controller.UnregisterDecoration(this); + } + + _isPlacedOnStatue = false; + _isDragging = true; + + // Calculate offset + RectTransformUtility.ScreenPointToLocalPointInRectangle( + _canvas.transform as RectTransform, + pointerPosition, + null, + out Vector2 localPoint); + + _dragOffset = _rectTransform.localPosition - (Vector3)localPoint; + + Logging.Debug($"[DecorationDraggableInstance] Started drag from statue: {_decorationData?.DecorationName}"); + } + } +} + diff --git a/Assets/Scripts/Minigames/StatueDressup/DragDrop/DecorationDraggableInstance.cs.meta b/Assets/Scripts/Minigames/StatueDressup/DragDrop/DecorationDraggableInstance.cs.meta new file mode 100644 index 00000000..ab89e5a6 --- /dev/null +++ b/Assets/Scripts/Minigames/StatueDressup/DragDrop/DecorationDraggableInstance.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e4659fd035c74a79af0311de9e17f44a +timeCreated: 1763991638 \ No newline at end of file diff --git a/Assets/Scripts/Minigames/StatueDressup/DragDrop/DecorationGridIcon.cs b/Assets/Scripts/Minigames/StatueDressup/DragDrop/DecorationGridIcon.cs new file mode 100644 index 00000000..d26874f4 --- /dev/null +++ b/Assets/Scripts/Minigames/StatueDressup/DragDrop/DecorationGridIcon.cs @@ -0,0 +1,100 @@ +using Core; +using Minigames.StatueDressup.Data; +using UnityEngine; +using UnityEngine.EventSystems; +using UnityEngine.UI; + +namespace Minigames.StatueDressup.DragDrop +{ + /// + /// Static grid icon for decorations in the menu. + /// Handles tap and drag initiation, but doesn't move itself. + /// Spawns a draggable instance when drag starts. + /// + public class DecorationGridIcon : MonoBehaviour, IPointerClickHandler, IBeginDragHandler, IDragHandler, IEndDragHandler + { + [Header("References")] + [SerializeField] private Image iconImage; + [SerializeField] private DecorationData decorationData; + + private Controllers.DecorationMenuController _menuController; + private DecorationDraggableInstance _activeDraggableInstance; + + // Properties + public DecorationData Data => decorationData; + + /// + /// Initialize the icon with decoration data + /// + public void Initialize(DecorationData data, Controllers.DecorationMenuController controller) + { + decorationData = data; + _menuController = controller; + + if (iconImage != null && data != null && data.DecorationSprite != null) + { + iconImage.sprite = data.DecorationSprite; + } + } + + /// + /// Handle tap/click on icon + /// + public void OnPointerClick(PointerEventData eventData) + { + // Only process clicks if we're not dragging + if (_activeDraggableInstance == null) + { + Logging.Debug($"[DecorationGridIcon] Item tapped: {decorationData?.DecorationName}"); + // Future: Open detail view, preview, etc. + } + } + + /// + /// Handle drag start - spawn draggable instance + /// + public void OnBeginDrag(PointerEventData eventData) + { + if (_menuController == null || decorationData == null) + { + Logging.Warning("[DecorationGridIcon] Cannot start drag - missing controller or data"); + return; + } + + Logging.Debug($"[DecorationGridIcon] Starting drag for: {decorationData.DecorationName}"); + + // Spawn draggable instance at cursor position + _activeDraggableInstance = _menuController.SpawnDraggableInstance(decorationData, eventData.position); + + // Start the drag on the spawned instance + if (_activeDraggableInstance != null) + { + _activeDraggableInstance.StartDragFromIcon(eventData); + } + } + + /// + /// Forward drag events to the active draggable instance + /// + public void OnDrag(PointerEventData eventData) + { + if (_activeDraggableInstance != null) + { + _activeDraggableInstance.ContinueDrag(eventData); + } + } + + /// + /// Forward drag end to the active draggable instance + /// + public void OnEndDrag(PointerEventData eventData) + { + if (_activeDraggableInstance != null) + { + _activeDraggableInstance.EndDrag(eventData); + _activeDraggableInstance = null; + } + } + } +} + diff --git a/Assets/Scripts/Minigames/StatueDressup/DragDrop/DecorationGridIcon.cs.meta b/Assets/Scripts/Minigames/StatueDressup/DragDrop/DecorationGridIcon.cs.meta new file mode 100644 index 00000000..6a273f13 --- /dev/null +++ b/Assets/Scripts/Minigames/StatueDressup/DragDrop/DecorationGridIcon.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9c806d80a321498c9f33f13d7a31065c +timeCreated: 1763991611 \ No newline at end of file diff --git a/Assets/Scripts/Minigames/StatueDressup/Utils.meta b/Assets/Scripts/Minigames/StatueDressup/Utils.meta new file mode 100644 index 00000000..e5d6ab01 --- /dev/null +++ b/Assets/Scripts/Minigames/StatueDressup/Utils.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: fe03648f638e4872abafaf49234a3f55 +timeCreated: 1763745490 \ No newline at end of file diff --git a/Assets/Scripts/Minigames/StatueDressup/Utils/TweenAnimationUtility.cs b/Assets/Scripts/Minigames/StatueDressup/Utils/TweenAnimationUtility.cs new file mode 100644 index 00000000..50699db0 --- /dev/null +++ b/Assets/Scripts/Minigames/StatueDressup/Utils/TweenAnimationUtility.cs @@ -0,0 +1,171 @@ +using Pixelplacement; +using Pixelplacement.TweenSystem; +using UnityEngine; +using System; + +namespace Minigames.StatueDressup.Utils +{ + /// + /// Common animation utilities extracted from CardAnimator pattern. + /// Provides reusable tween animations for UI elements. + /// + public static class TweenAnimationUtility + { + #region Scale Animations + + /// + /// Animate scale to target value with ease in-out + /// + public static TweenBase AnimateScale(Transform transform, Vector3 targetScale, float duration, Action onComplete = null) + { + return Tween.LocalScale(transform, targetScale, duration, 0f, Tween.EaseInOut, completeCallback: onComplete); + } + + /// + /// Pulse scale animation (scale up then back to original) + /// + public static void PulseScale(Transform transform, float pulseAmount = 1.1f, float duration = 0.2f, Action onComplete = null) + { + Vector3 originalScale = transform.localScale; + Vector3 pulseScale = originalScale * pulseAmount; + + Tween.LocalScale(transform, pulseScale, duration, 0f, Tween.EaseOutBack, + completeCallback: () => + { + Tween.LocalScale(transform, originalScale, duration, 0f, Tween.EaseInBack, completeCallback: onComplete); + }); + } + + /// + /// Pop-in animation (scale from 0 to target with overshoot) + /// + public static TweenBase PopIn(Transform transform, Vector3 targetScale, float duration = 0.5f, Action onComplete = null) + { + transform.localScale = Vector3.zero; + return Tween.LocalScale(transform, targetScale, duration, 0f, Tween.EaseOutBack, completeCallback: onComplete); + } + + /// + /// Pop-out animation (scale from current to 0) + /// + public static TweenBase PopOut(Transform transform, float duration = 0.3f, Action onComplete = null) + { + return Tween.LocalScale(transform, Vector3.zero, duration, 0f, Tween.EaseInBack, completeCallback: onComplete); + } + + /// + /// Smooth scale transition with bounce + /// + public static TweenBase ScaleWithBounce(Transform transform, Vector3 targetScale, float duration, Action onComplete = null) + { + return Tween.LocalScale(transform, targetScale, duration, 0f, Tween.EaseOutBack, completeCallback: onComplete); + } + + #endregion + + #region Position Animations + + /// + /// Animate anchored position (for RectTransform UI elements) + /// + public static TweenBase AnimateAnchoredPosition(RectTransform rectTransform, Vector2 targetPosition, float duration, Action onComplete = null) + { + return Tween.AnchoredPosition(rectTransform, targetPosition, duration, 0f, Tween.EaseInOut, completeCallback: onComplete); + } + + /// + /// Animate local position (for regular transforms) + /// + public static TweenBase AnimateLocalPosition(Transform transform, Vector3 targetPosition, float duration, Action onComplete = null) + { + return Tween.LocalPosition(transform, targetPosition, duration, 0f, Tween.EaseInOut, completeCallback: onComplete); + } + + /// + /// Move with bounce effect + /// + public static TweenBase MoveWithBounce(RectTransform rectTransform, Vector2 targetPosition, float duration, Action onComplete = null) + { + return Tween.AnchoredPosition(rectTransform, targetPosition, duration, 0f, Tween.EaseOutBack, completeCallback: onComplete); + } + + #endregion + + #region Combined Hover Animations + + /// + /// Hover enter animation (lift and scale) for RectTransform + /// + public static void HoverEnter(RectTransform rectTransform, Vector2 originalPosition, float liftAmount = 20f, + float scaleMultiplier = 1.05f, float duration = 0.2f, Action onComplete = null) + { + Vector2 targetPos = originalPosition + Vector2.up * liftAmount; + + Tween.AnchoredPosition(rectTransform, targetPos, duration, 0f, Tween.EaseOutBack); + Tween.LocalScale(rectTransform, Vector3.one * scaleMultiplier, duration, 0f, Tween.EaseOutBack, completeCallback: onComplete); + } + + /// + /// Hover exit animation (return to original position and scale) for RectTransform + /// + public static void HoverExit(RectTransform rectTransform, Vector2 originalPosition, float duration = 0.2f, Action onComplete = null) + { + Tween.AnchoredPosition(rectTransform, originalPosition, duration, 0f, Tween.EaseInBack); + Tween.LocalScale(rectTransform, Vector3.one, duration, 0f, Tween.EaseInBack, completeCallback: onComplete); + } + + /// + /// Glow pulse effect (scale up/down repeatedly) + /// + public static TweenBase StartGlowPulse(Transform transform, float pulseAmount = 1.1f, float duration = 0.8f) + { + Vector3 originalScale = transform.localScale; + Vector3 pulseScale = originalScale * pulseAmount; + + return Tween.LocalScale(transform, pulseScale, duration, 0f, Tween.EaseIn, Tween.LoopType.PingPong); + } + + /// + /// Stop any active tweens on transform + /// + public static void StopTweens(Transform transform) + { + Tween.Cancel(transform.GetInstanceID()); + } + + #endregion + + #region Fade Animations + + /// + /// Fade CanvasGroup alpha + /// + public static TweenBase FadeCanvasGroup(CanvasGroup canvasGroup, float targetAlpha, float duration, Action onComplete = null) + { + return Tween.CanvasGroupAlpha(canvasGroup, targetAlpha, duration, 0f, Tween.EaseInOut, completeCallback: onComplete); + } + + /// + /// Pop-out with fade - scale to 0 and fade out simultaneously + /// + public static void PopOutWithFade(Transform transform, CanvasGroup canvasGroup, float duration, Action onComplete = null) + { + // Scale to 0 + Tween.LocalScale(transform, Vector3.zero, duration, 0f, Tween.EaseInBack); + + // Fade out simultaneously + if (canvasGroup != null) + { + Tween.CanvasGroupAlpha(canvasGroup, 0f, duration, 0f, Tween.EaseInOut, completeCallback: onComplete); + } + else + { + // If no canvas group, just call complete after scale + Tween.LocalScale(transform, Vector3.zero, duration, 0f, Tween.EaseInBack, completeCallback: onComplete); + } + } + + #endregion + } +} + diff --git a/Assets/Scripts/Minigames/StatueDressup/Utils/TweenAnimationUtility.cs.meta b/Assets/Scripts/Minigames/StatueDressup/Utils/TweenAnimationUtility.cs.meta new file mode 100644 index 00000000..b9195d9c --- /dev/null +++ b/Assets/Scripts/Minigames/StatueDressup/Utils/TweenAnimationUtility.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: abd48147eff149508890fe2fa87b8421 +timeCreated: 1763745490 \ No newline at end of file diff --git a/Assets/Scripts/UI/PlayerHudManager.cs b/Assets/Scripts/UI/PlayerHudManager.cs index 9726464d..00eba7a4 100644 --- a/Assets/Scripts/UI/PlayerHudManager.cs +++ b/Assets/Scripts/UI/PlayerHudManager.cs @@ -235,7 +235,7 @@ namespace UI case "Quarry": currentUIMode = UIMode.Puzzle; break; - case "DivingForPictures" or "CardQualityControl" or "BirdPoop": + case "DivingForPictures" or "CardQualityControl" or "BirdPoop" or "StatueDecoration": currentUIMode = UIMode.Minigame; break; } diff --git a/Assets/Settings/BirdPooperSettings.asset b/Assets/Settings/BirdPooperSettings.asset index 01c8f989..2f32e1bc 100644 --- a/Assets/Settings/BirdPooperSettings.asset +++ b/Assets/Settings/BirdPooperSettings.asset @@ -27,3 +27,5 @@ MonoBehaviour: obstacleMaxSpawnY: 3 poopFallSpeed: 10 poopDestroyYPosition: -20 + targetMoveSpeed: 4 + targetSpawnInterval: 3 diff --git a/Assets/Settings/InteractionSettings.asset b/Assets/Settings/InteractionSettings.asset index 3eafb89f..1eac67e5 100644 --- a/Assets/Settings/InteractionSettings.asset +++ b/Assets/Settings/InteractionSettings.asset @@ -35,19 +35,24 @@ MonoBehaviour: allowedItems: - {fileID: 11400000, guid: ecae2d83a5ab2a047a2733ebff607380, type: 2} forbiddenItems: [] + requiredItemCount: 0 - slotItem: {fileID: 11400000, guid: f97b9e24d6dceb145b56426c1152ebeb, type: 2} allowedItems: - {fileID: 11400000, guid: ff4bbba87722023468a0f6395d1f96c7, type: 2} forbiddenItems: [] + requiredItemCount: 0 - slotItem: {fileID: 11400000, guid: d28f5774afad9d14f823601707150700, type: 2} allowedItems: - {fileID: 11400000, guid: 6934dcb56c610c44da228f7f24ca13c9, type: 2} forbiddenItems: [] + requiredItemCount: 0 - slotItem: {fileID: 11400000, guid: aaf36cd26cf74334e9c7db6c1b03b3fb, type: 2} allowedItems: - {fileID: 11400000, guid: c50330645a2b9d549aae3639bdfcea19, type: 2} forbiddenItems: [] + requiredItemCount: 0 - slotItem: {fileID: 11400000, guid: c68dea945fecbf44094359769db04f31, type: 2} allowedItems: - {fileID: 11400000, guid: ab57c8237aac144439a18d69f56d36c6, type: 2} forbiddenItems: [] + requiredItemCount: 0 diff --git a/Assets/Settings/StatueDressupSettings.asset b/Assets/Settings/StatueDressupSettings.asset new file mode 100644 index 00000000..2a7a1887 --- /dev/null +++ b/Assets/Settings/StatueDressupSettings.asset @@ -0,0 +1,44 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4fcf232a64e34f489b874519cc96339e, type: 3} + m_Name: StatueDressupSettings + m_EditorClassIdentifier: AppleHillsScripts::Core.Settings.StatueDressupSettings + defaultIconSize: {x: 64, y: 64} + defaultAuthoredSize: {x: 128, y: 128} + allDecorations: + - {fileID: 11400000, guid: 2ea75de9ff6dbfb4b8c246a654868479, type: 2} + - {fileID: 11400000, guid: ca949a6208ce5b5488e90ea3e2eed6df, type: 2} + - {fileID: 11400000, guid: 5efa934e009bc234e920904b05db3c2f, type: 2} + - {fileID: 11400000, guid: 8819ec8b1f4910a4494755cf043636d1, type: 2} + - {fileID: 11400000, guid: b09b79db8ef15144bb2138ec59f26a9c, type: 2} + - {fileID: 11400000, guid: 8838477f768600848813a215ab6a46fe, type: 2} + - {fileID: 11400000, guid: f0df83df3cff9d84ba9fd4895e5d1b58, type: 2} + - {fileID: 11400000, guid: 4101d48e428899d409df02f24c83571f, type: 2} + - {fileID: 11400000, guid: b01ee8334ee052b4784225337e9a5ece, type: 2} + - {fileID: 11400000, guid: a5d493c2c7c9cf74cab038023b401273, type: 2} + itemsPerPage: 8 + gridColumns: 2 + gridSpacing: {x: 10, y: 10} + dragScaleTransitionDuration: 0.2 + returnToMenuDuration: 0.3 + minOverlapPercentage: 0.1 + hoverScaleMultiplier: 1.05 + hoverAnimationDuration: 0.2 + placementAnimationDuration: 0.15 + photoSaveKey: MrCementStatuePhoto + photoQuality: 85 + captureFullScreen: 0 + cardsRewardCount: 3 + autoCompleteOnPhoto: 1 + enableStatePersistence: 1 + stateSaveKey: StatueDecorationState + maxSavedDecorations: 50 diff --git a/Assets/Settings/StatueDressupSettings.asset.meta b/Assets/Settings/StatueDressupSettings.asset.meta new file mode 100644 index 00000000..3884a0e1 --- /dev/null +++ b/Assets/Settings/StatueDressupSettings.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 359004e51663d6442b7d2b960d12b459 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: