diff --git a/Assets/Editor/ObjectiveStepBehaviourEditor.cs b/Assets/Editor/ObjectiveStepBehaviourEditor.cs deleted file mode 100644 index bd4f82cc..00000000 --- a/Assets/Editor/ObjectiveStepBehaviourEditor.cs +++ /dev/null @@ -1,57 +0,0 @@ -using UnityEngine; -using UnityEditor; -using AppleHills.Editor; -using AppleHills.Core.Settings; - -namespace PuzzleS.Editor -{ - [CustomEditor(typeof(ObjectiveStepBehaviour))] - public class ObjectiveStepBehaviourEditor : UnityEditor.Editor - { - private SerializedProperty stepDataProperty; - private SerializedProperty indicatorPrefabProperty; - private SerializedProperty drawPromptRangeGizmoProperty; - - private void OnEnable() - { - stepDataProperty = serializedObject.FindProperty("stepData"); - indicatorPrefabProperty = serializedObject.FindProperty("indicatorPrefab"); - drawPromptRangeGizmoProperty = serializedObject.FindProperty("drawPromptRangeGizmo"); - } - - public override void OnInspectorGUI() - { - serializedObject.Update(); - - // Draw default inspector properties - EditorGUILayout.PropertyField(stepDataProperty); - - EditorGUILayout.Space(); - EditorGUILayout.LabelField("Indicator Settings", EditorStyles.boldLabel); - EditorGUILayout.PropertyField(indicatorPrefabProperty); - EditorGUILayout.PropertyField(drawPromptRangeGizmoProperty); - - // Add button to create default indicator - EditorGUILayout.Space(); - if (GUILayout.Button("Create Default Indicator")) - { - var interactionSettings = EditorSettingsProvider.GetSettings(); - if (interactionSettings != null && interactionSettings.DefaultPuzzleIndicatorPrefab != null) - { - indicatorPrefabProperty.objectReferenceValue = interactionSettings.DefaultPuzzleIndicatorPrefab; - serializedObject.ApplyModifiedProperties(); - - Debug.Log("Default puzzle indicator prefab assigned from settings"); - } - else - { - Debug.LogWarning("Default puzzle indicator prefab not set in InteractionSettings!"); - EditorUtility.DisplayDialog("No Default Indicator", - "The default puzzle indicator prefab is not set in the InteractionSettings asset.", "OK"); - } - } - - serializedObject.ApplyModifiedProperties(); - } - } -} diff --git a/Assets/Editor/ObjectiveStepBehaviourEditor.cs.meta b/Assets/Editor/ObjectiveStepBehaviourEditor.cs.meta deleted file mode 100644 index c968817b..00000000 --- a/Assets/Editor/ObjectiveStepBehaviourEditor.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: ba55b805a871449e9429e1a210f22fed -timeCreated: 1759312523 \ No newline at end of file diff --git a/Assets/Prefabs/Puzzles/BasePuzzlePickup.prefab b/Assets/Prefabs/Puzzles/BasePuzzlePickup.prefab index c52311f4..20db50ab 100644 --- a/Assets/Prefabs/Puzzles/BasePuzzlePickup.prefab +++ b/Assets/Prefabs/Puzzles/BasePuzzlePickup.prefab @@ -78,3 +78,5 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: stepData: {fileID: 0} + puzzleIndicator: {fileID: 0} + drawPromptRangeGizmo: 1 diff --git a/Assets/Scenes/Levels/AppleHillsOverworld.unity b/Assets/Scenes/Levels/AppleHillsOverworld.unity index 8b60bbdf..4fe71ee7 100644 --- a/Assets/Scenes/Levels/AppleHillsOverworld.unity +++ b/Assets/Scenes/Levels/AppleHillsOverworld.unity @@ -303,6 +303,10 @@ PrefabInstance: propertyPath: indicatorPrefab value: objectReference: {fileID: 517425340} + - target: {fileID: 4778083634590203921, guid: b5fc01af35233eb4cbeede05e50a7c34, type: 3} + propertyPath: puzzleIndicator + value: + objectReference: {fileID: 517425340} - target: {fileID: 6254953093500072797, guid: b5fc01af35233eb4cbeede05e50a7c34, type: 3} propertyPath: characterToInteract value: 1 @@ -585,6 +589,14 @@ PrefabInstance: propertyPath: m_Enabled value: 1 objectReference: {fileID: 0} + - target: {fileID: 4778083634590203921, guid: b5fc01af35233eb4cbeede05e50a7c34, type: 3} + propertyPath: indicatorPrefab + value: + objectReference: {fileID: 1398956015} + - target: {fileID: 4778083634590203921, guid: b5fc01af35233eb4cbeede05e50a7c34, type: 3} + propertyPath: puzzleIndicator + value: + objectReference: {fileID: 1398956015} - target: {fileID: 6254953093500072797, guid: b5fc01af35233eb4cbeede05e50a7c34, type: 3} propertyPath: isOneTime value: 0 @@ -599,7 +611,10 @@ PrefabInstance: objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] - m_AddedGameObjects: [] + m_AddedGameObjects: + - targetCorrespondingSourceObject: {fileID: 2844046668579196942, guid: b5fc01af35233eb4cbeede05e50a7c34, type: 3} + insertIndex: -1 + addedObject: {fileID: 2027386480} m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: b5fc01af35233eb4cbeede05e50a7c34, type: 3} --- !u!1 &384576743 @@ -1969,6 +1984,11 @@ PrefabInstance: insertIndex: -1 addedObject: {fileID: 1631660124} m_SourcePrefab: {fileID: 100100000, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3} +--- !u!1 &1398956015 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 4963699568605073487, guid: cac39b7f8f414e7499e7b672d8710642, type: 3} + m_PrefabInstance: {fileID: 2027386479} + m_PrefabAsset: {fileID: 0} --- !u!1 &1443361595 GameObject: m_ObjectHideFlags: 0 @@ -2638,6 +2658,80 @@ Transform: m_Children: [] m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1001 &2027386479 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 754397347} + m_Modifications: + - target: {fileID: 4963699568605073487, guid: cac39b7f8f414e7499e7b672d8710642, type: 3} + propertyPath: m_Name + value: TestIndicator + objectReference: {fileID: 0} + - target: {fileID: 6675530734045362487, guid: cac39b7f8f414e7499e7b672d8710642, type: 3} + propertyPath: m_LocalScale.x + value: -0.02 + objectReference: {fileID: 0} + - target: {fileID: 6675530734045362487, guid: cac39b7f8f414e7499e7b672d8710642, type: 3} + propertyPath: m_LocalScale.y + value: 0.022568762 + objectReference: {fileID: 0} + - target: {fileID: 6675530734045362487, guid: cac39b7f8f414e7499e7b672d8710642, type: 3} + propertyPath: m_LocalScale.z + value: 0.36117727 + objectReference: {fileID: 0} + - target: {fileID: 6675530734045362487, guid: cac39b7f8f414e7499e7b672d8710642, type: 3} + propertyPath: m_LocalPosition.x + value: 0.62 + objectReference: {fileID: 0} + - target: {fileID: 6675530734045362487, guid: cac39b7f8f414e7499e7b672d8710642, type: 3} + propertyPath: m_LocalPosition.y + value: 0.53 + objectReference: {fileID: 0} + - target: {fileID: 6675530734045362487, guid: cac39b7f8f414e7499e7b672d8710642, type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6675530734045362487, guid: cac39b7f8f414e7499e7b672d8710642, type: 3} + propertyPath: m_LocalRotation.w + value: -0.020675343 + objectReference: {fileID: 0} + - target: {fileID: 6675530734045362487, guid: cac39b7f8f414e7499e7b672d8710642, type: 3} + propertyPath: m_LocalRotation.x + value: -0 + objectReference: {fileID: 0} + - target: {fileID: 6675530734045362487, guid: cac39b7f8f414e7499e7b672d8710642, type: 3} + propertyPath: m_LocalRotation.y + value: -0 + objectReference: {fileID: 0} + - target: {fileID: 6675530734045362487, guid: cac39b7f8f414e7499e7b672d8710642, type: 3} + propertyPath: m_LocalRotation.z + value: 0.99978626 + objectReference: {fileID: 0} + - target: {fileID: 6675530734045362487, guid: cac39b7f8f414e7499e7b672d8710642, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6675530734045362487, guid: cac39b7f8f414e7499e7b672d8710642, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6675530734045362487, guid: cac39b7f8f414e7499e7b672d8710642, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 182.369 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: cac39b7f8f414e7499e7b672d8710642, type: 3} +--- !u!4 &2027386480 stripped +Transform: + m_CorrespondingSourceObject: {fileID: 6675530734045362487, guid: cac39b7f8f414e7499e7b672d8710642, type: 3} + m_PrefabInstance: {fileID: 2027386479} + m_PrefabAsset: {fileID: 0} --- !u!4 &2102167558 stripped Transform: m_CorrespondingSourceObject: {fileID: 2844046668579196942, guid: b5fc01af35233eb4cbeede05e50a7c34, type: 3} diff --git a/Assets/Scripts/PuzzleS/IPuzzlePrompt.cs b/Assets/Scripts/PuzzleS/IPuzzlePrompt.cs index fd692745..158a55f8 100644 --- a/Assets/Scripts/PuzzleS/IPuzzlePrompt.cs +++ b/Assets/Scripts/PuzzleS/IPuzzlePrompt.cs @@ -8,6 +8,16 @@ namespace PuzzleS /// public interface IPuzzlePrompt { + /// + /// Called when the prompt should be initially shown (e.g., when step is unlocked) + /// + void OnShow(); + + /// + /// Called when the prompt should be hidden (e.g., when step is locked) + /// + void OnHide(); + /// /// Called when the player enters the outer range of the prompt. /// diff --git a/Assets/Scripts/PuzzleS/ObjectiveStepBehaviour.cs b/Assets/Scripts/PuzzleS/ObjectiveStepBehaviour.cs index 8950af2b..e0a7f3ea 100644 --- a/Assets/Scripts/PuzzleS/ObjectiveStepBehaviour.cs +++ b/Assets/Scripts/PuzzleS/ObjectiveStepBehaviour.cs @@ -3,6 +3,7 @@ using Interactions; using UnityEngine; using System; using AppleHills.Core.Settings; +using UnityEngine.Serialization; namespace PuzzleS { @@ -18,12 +19,11 @@ namespace PuzzleS public PuzzleStepSO stepData; [Header("Indicator Settings")] - [SerializeField] private GameObject indicatorPrefab; + [SerializeField] private GameObject puzzleIndicator; [SerializeField] private bool drawPromptRangeGizmo = true; private Interactable _interactable; private bool _isUnlocked = false; - private GameObject _spawnedIndicator; private IPuzzlePrompt _indicator; // Current proximity state tracked by PuzzleManager @@ -62,14 +62,6 @@ namespace PuzzleS _interactable.interactionComplete.RemoveListener(OnInteractionComplete); } PuzzleManager.Instance?.UnregisterStepBehaviour(this); - - // Clean up indicator - if (_spawnedIndicator != null) - { - Destroy(_spawnedIndicator); - _spawnedIndicator = null; - _indicator = null; - } } /// @@ -97,11 +89,46 @@ namespace PuzzleS // IPuzzlePrompt interface implementation - delegates to indicator if available + /// + /// Called when the prompt should be initially shown (e.g., when step is unlocked) + /// + public virtual void OnShow() + { + // Delegate to indicator if available + if (_indicator != null) + { + _indicator.OnShow(); + return; + } + + // Default fallback behavior + Debug.Log($"[Puzzles] Prompt shown for {stepData?.stepId} on {gameObject.name}"); + } + + /// + /// Called when the prompt should be hidden (e.g., when step is locked) + /// + public virtual void OnHide() + { + // Delegate to indicator if available + if (_indicator != null) + { + _indicator.OnHide(); + return; + } + + // Default fallback behavior + Debug.Log($"[Puzzles] Prompt hidden for {stepData?.stepId} on {gameObject.name}"); + } + /// /// Called when player enters the far range /// public virtual void ShowFar() { + // Only show if step is unlocked + if (!_isUnlocked) return; + // Delegate to indicator if available if (_indicator != null) { @@ -118,6 +145,9 @@ namespace PuzzleS /// public virtual void ShowClose() { + // Only show if step is unlocked + if (!_isUnlocked) return; + // Delegate to indicator if available if (_indicator != null) { @@ -134,6 +164,9 @@ namespace PuzzleS /// public virtual void HideClose() { + // Only respond if step is unlocked + if (!_isUnlocked) return; + // Delegate to indicator if available if (_indicator != null) { @@ -150,6 +183,9 @@ namespace PuzzleS /// public virtual void HideFar() { + // Only respond if step is unlocked + if (!_isUnlocked) return; + // Delegate to indicator if available if (_indicator != null) { @@ -170,16 +206,15 @@ namespace PuzzleS Debug.Log($"[Puzzles] Step unlocked: {stepData?.stepId} on {gameObject.name}"); // Show indicator if enabled in settings - if (stepData?.ShowIndicator == true && indicatorPrefab != null && _spawnedIndicator == null) + if (puzzleIndicator != null) { - _spawnedIndicator = Instantiate(indicatorPrefab, transform); // Try to get the IPuzzlePrompt component from the spawned indicator - _indicator = _spawnedIndicator.GetComponent(); + _indicator = puzzleIndicator.GetComponent(); if (_indicator == null) { // Try to find it in children if not on the root - _indicator = _spawnedIndicator.GetComponentInChildren(); + _indicator = puzzleIndicator.GetComponentInChildren(); } if (_indicator == null) @@ -188,7 +223,10 @@ namespace PuzzleS } else { - // Immediately set the correct state based on current player distance + // First show the indicator + _indicator.OnShow(); + + // Then set the correct state based on current player distance Transform playerTransform = GameObject.FindGameObjectWithTag("Player")?.transform; if (playerTransform != null) { @@ -227,11 +265,9 @@ namespace PuzzleS Debug.Log($"[Puzzles] Step locked: {stepData?.stepId} on {gameObject.name}"); // Hide indicator - if (_spawnedIndicator != null) + if (_indicator != null) { - Destroy(_spawnedIndicator); - _spawnedIndicator = null; - _indicator = null; + _indicator.OnHide(); } } diff --git a/Assets/Scripts/UI/TestIndicator.cs b/Assets/Scripts/UI/TestIndicator.cs index 79e6ea83..ae2dcbf2 100644 --- a/Assets/Scripts/UI/TestIndicator.cs +++ b/Assets/Scripts/UI/TestIndicator.cs @@ -14,6 +14,16 @@ public class TestIndicator : MonoBehaviour, PuzzleS.IPuzzlePrompt } + public void OnShow() + { + gameObject.SetActive(true); + } + + public void OnHide() + { + gameObject.SetActive(false); + } + public void ShowFar() { gameObject.SetActive(true);