using System; using UnityEngine; public class TiltHoleMiniGameManager : MonoBehaviour, ITask { // ========================= // ITask PROPERTIES // ========================= public string TaskID { get; private set; } = "TILT_HOLE_01"; public TaskType TaskType { get; private set; } = TaskType.Task; public string TaskName { get; private set; } = "Tilt Ball Into Hole"; public (double, double) TaskLocation { get; private set; } = (0, 0); public bool IsCompleted { get; private set; } private Action _onCompletedCallback; // ========================= // MINIGAME REFERENCES // ========================= [Header("References")] public GyroPlatformController platformController; public HoleGoalTrigger goalTrigger; public Rigidbody ball; [Header("Audio")] public AudioClip startSound; public AudioClip winSound; private AudioSource audioSource; [Header("Game State")] public bool isActive = false; [Header("Win Behavior")] public bool freezeOnWin = true; public bool disableBallOnWin = false; // ========================= // UNITY LIFECYCLE // ========================= void Awake() { if (platformController == null) platformController = FindFirstObjectByType(); if (goalTrigger == null) goalTrigger = FindFirstObjectByType(); if (Camera.main != null) { audioSource = Camera.main.GetComponent(); if (audioSource == null) audioSource = Camera.main.gameObject.AddComponent(); } } void Start() { if (goalTrigger != null) { goalTrigger.OnBallScored += HandleWin; } if (ball != null && goalTrigger != null) { goalTrigger.ballRigidbody = ball; } } void OnDestroy() { if (goalTrigger != null) goalTrigger.OnBallScored -= HandleWin; } // ========================= // TASK LIFECYCLE // ========================= public void Initialize(Action onCompleted) { Debug.Log("Initializing Tilt Hole Task"); IsCompleted = false; isActive = true; _onCompletedCallback = onCompleted; if (platformController != null) platformController.enabled = true; if (ball != null) { ball.isKinematic = false; ball.linearVelocity = Vector3.zero; ball.angularVelocity = Vector3.zero; } if (startSound != null && audioSource != null) { audioSource.PlayOneShot(startSound); } } public void ExitTask(Action onExit) { Debug.Log("Exiting Tilt Hole Task"); isActive = false; if (platformController != null) platformController.enabled = false; onExit?.Invoke(this); } public void Complete() { if (IsCompleted) return; Debug.Log("Task Complete: Tilt Hole"); IsCompleted = true; isActive = false; if (winSound != null && audioSource != null) { audioSource.PlayOneShot(winSound); } _onCompletedCallback?.Invoke(this); ExitTask(null); } // ========================= // MINIGAME WIN EVENT // ========================= private void HandleWin() { if (!isActive) return; Debug.Log("Ball reached hole."); if (freezeOnWin) { if (platformController != null) platformController.enabled = false; if (ball != null) { ball.linearVelocity = Vector3.zero; ball.angularVelocity = Vector3.zero; ball.isKinematic = true; } } if (disableBallOnWin && ball != null) { ball.gameObject.SetActive(false); } Complete(); // 🔥 THIS completes the task } // ========================= // DEBUG GUI // ========================= void OnGUI() { GUIStyle s = new GUIStyle(GUI.skin.label); s.fontSize = 24; if (isActive) { s.normal.textColor = Color.white; GUI.Label(new Rect(10, 10, 700, 30), "Goal: Tilt platform to roll the ball into the hole.", s); } else if (IsCompleted) { s.normal.textColor = Color.yellow; GUI.Label(new Rect(10, 10, 700, 30), "Task Completed!", s); } } }