using UnityEngine; using UnityEngine.Events; [DisallowMultipleComponent] public class MemoryPieceReward : MonoBehaviour { [Header("Reference")] [SerializeField] private MemoryProgressManager memoryProgressManager; [Header("Reward")] [SerializeField] private int rewardAmount = 1; [SerializeField] private bool giveOnlyOnce = true; [Header("Persistent Reward ID")] [Tooltip("체크하면 같은 Reward ID는 게임을 다시 켜도 한 번만 지급됩니다.")] [SerializeField] private bool persistRewardGiven = true; [Tooltip("보상마다 고유 ID를 넣으세요. 예: Maze_Clear_Reward_01, WhalePuzzle_Clear_Reward_01")] [SerializeField] private string rewardId = "Maze_Clear_Reward_01"; [Header("Auto Find")] [SerializeField] private bool autoFindManager = true; [Header("Events")] public UnityEvent onRewardGiven = new UnityEvent(); public UnityEvent onRewardAlreadyGiven = new UnityEvent(); public UnityEvent onRewardFailed = new UnityEvent(); [Tooltip("진행도가 이미 완료되어 추가 보상이 필요 없는 경우 호출됩니다.")] public UnityEvent onRewardNoNeedAlreadyCompleted = new UnityEvent(); [Header("Debug")] [SerializeField] private bool showDebugLog = true; private bool alreadyGiven; private string RewardSaveKey => $"MemoryPieceReward_{rewardId}"; private void Awake() { if (memoryProgressManager == null && autoFindManager) memoryProgressManager = FindFirstObjectByType(); if (giveOnlyOnce && persistRewardGiven && !string.IsNullOrWhiteSpace(rewardId)) alreadyGiven = PlayerPrefs.GetInt(RewardSaveKey, 0) == 1; } public void GiveReward() { if (giveOnlyOnce && alreadyGiven) { onRewardAlreadyGiven?.Invoke(); if (showDebugLog) Debug.Log($"[MemoryPieceReward] 이미 지급된 기억의 조각입니다. Reward ID={rewardId}", this); return; } if (memoryProgressManager == null) { Debug.LogWarning("[MemoryPieceReward] MemoryProgressManager가 연결되지 않았습니다.", this); onRewardFailed?.Invoke(); return; } if (memoryProgressManager.IsCompleted) { if (showDebugLog) Debug.Log("[MemoryPieceReward] 기억의 조각 진행도가 이미 완료되어 추가 지급이 필요 없습니다.", this); onRewardNoNeedAlreadyCompleted?.Invoke(); return; } int addedAmount = memoryProgressManager.AddMemoryPiece(rewardAmount); if (addedAmount <= 0) { if (showDebugLog) Debug.Log("[MemoryPieceReward] 실제로 추가된 기억의 조각이 없습니다.", this); onRewardFailed?.Invoke(); return; } alreadyGiven = true; SaveRewardGivenIfNeeded(); onRewardGiven?.Invoke(); if (showDebugLog) Debug.Log($"[MemoryPieceReward] 기억의 조각 +{addedAmount}, Reward ID={rewardId}", this); } public void ResetReward() { alreadyGiven = false; if (persistRewardGiven && !string.IsNullOrWhiteSpace(rewardId)) { PlayerPrefs.DeleteKey(RewardSaveKey); PlayerPrefs.Save(); } if (showDebugLog) Debug.Log($"[MemoryPieceReward] 보상 지급 상태를 초기화했습니다. Reward ID={rewardId}", this); } public void SetMemoryProgressManager(MemoryProgressManager manager) { memoryProgressManager = manager; } public void SetRewardId(string id) { rewardId = id; } public bool IsRewardGiven() { return alreadyGiven; } private void SaveRewardGivenIfNeeded() { if (!giveOnlyOnce || !persistRewardGiven) return; if (string.IsNullOrWhiteSpace(rewardId)) { Debug.LogWarning("[MemoryPieceReward] Reward ID가 비어 있어 지급 상태를 저장하지 않았습니다.", this); return; } PlayerPrefs.SetInt(RewardSaveKey, 1); PlayerPrefs.Save(); } #if UNITY_EDITOR private void OnValidate() { rewardAmount = Mathf.Max(1, rewardAmount); if (persistRewardGiven && string.IsNullOrWhiteSpace(rewardId)) { Debug.LogWarning("MemoryPieceReward: Persist Reward Given이 켜져 있지만 Reward ID가 비어 있습니다.", this); } if (persistRewardGiven && rewardId == "MazeReward_01") { Debug.LogWarning("MemoryPieceReward: 기본 Reward ID를 그대로 쓰고 있습니다. 보상마다 고유 ID로 바꾸는 것을 추천합니다.", this); } } #endif }