using UnityEngine; using System; using System.Collections; using UnityEngine.Events; public class ChildrenLoopManager : MonoBehaviour { [Header("Children Loops Setup")] [Tooltip("Check if we're loading a saved game in the Children Loops section")] [SerializeField] private Transform playerNewGameStartPosition; public bool isLoadingChildrenLoops; [Header("Puzzle Objects")] [Tooltip("Reference to the puzzle GameObject if applicable")] [SerializeField] private GameObject puzzleGameObject; [Tooltip("Optional puzzle solved effects, if needed")] [SerializeField] private GameObject puzzleSolvedEffects; public ChildrenLoopsEventsData childrenLoopsEventsData; public ChildrenLoopsPuzzlesData childrenLoopsPuzzlesData; // 1. Define the loop states (8 loops + 1 puzzle) public enum ChildrenLoopState { CheckLoad, LongHallway, Loop1, Loop2, Loop3, Loop4, Loop5, Loop6, Loop7, Loop8, Puzzle } // Current loop state public ChildrenLoopState currentChildrenLoopState = ChildrenLoopState.Loop1; private void Awake() { // Assign this manager to GameManager so it can be activated/deactivated appropriately if (GameManager.GetInstance() != null) { GameManager.GetInstance().childrenLoopManager = this; } // If we are loading a saved game, mark accordingly if (LoadManager.GetInstance() != null && LoadManager.GetInstance().LoadingGame) { isLoadingChildrenLoops = true; } } public void Activate() { Logger.Log("Children Loops Manager Activated: Initializing Children Loops."); //TryLoadSavedState(); UpdateStoryline(); } public void Deactivate() { Logger.Log("Children Loops Manager Deactivated."); StopAllCoroutines(); SaveStorylineState(); CleanupPlayerSettings(); // If you want to automatically progress upon deactivation, uncomment below: // NotifyCompletion(); } public void UpdateStoryline() { switch (currentChildrenLoopState) { case ChildrenLoopState.CheckLoad: HandleCheckLoadState(); break; case ChildrenLoopState.LongHallway: Logger.Log("Children Loop Long Hallway activated."); if (isLoadingChildrenLoops) { isLoadingChildrenLoops = false; } childrenLoopsEventsData.StartOfLongHallwayLeadingToLoops.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Loop1: Logger.Log("Children Loop 1 activated."); if (isLoadingChildrenLoops) { isLoadingChildrenLoops = false; } childrenLoopsEventsData.StartOfLoop1Event.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Loop2: Logger.Log("Children Loop 2 activated."); if (isLoadingChildrenLoops) { isLoadingChildrenLoops = false; } childrenLoopsEventsData.StartOfLoop2Event.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Loop3: Logger.Log("Children Loop 3 activated."); if (isLoadingChildrenLoops) { isLoadingChildrenLoops = false; } #region Light Switches Puzzle Related: foreach (var lightSwitch in childrenLoopsPuzzlesData.ManageLightSwitchesInLoop3.lightSwitch) { lightSwitch.onLightSwitchTurnedOn += childrenLoopsPuzzlesData.lightsSwitchesPuzzleInLoop3.CheckPuzzleCombination; lightSwitch.onLightSwitchTurnedOff += childrenLoopsPuzzlesData.lightsSwitchesPuzzleInLoop3.CheckPuzzleCombination; } //YOU NEED TO LATER UNSUBSCRIBE THE LIGHT SWITCHES! #endregion childrenLoopsEventsData.StartOfLoop3Event.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Loop4: Logger.Log("Children Loop 4 activated."); if (isLoadingChildrenLoops) { isLoadingChildrenLoops = false; } childrenLoopsEventsData.StartOfLoop4Event.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Loop5: Logger.Log("Children Loop 5 activated."); if (isLoadingChildrenLoops) { isLoadingChildrenLoops = false; } childrenLoopsEventsData.StartOfLoop5Event.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Loop6: Logger.Log("Children Loop 6 activated."); if (isLoadingChildrenLoops) { isLoadingChildrenLoops = false; } childrenLoopsEventsData.StartOfLoop6Event.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Loop7: Logger.Log("Children Loop 7 activated."); if (isLoadingChildrenLoops) { isLoadingChildrenLoops = false; } childrenLoopsEventsData.StartOfLoop7Event.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Loop8: Logger.Log("Children Loop 8 activated (final loop before puzzle)."); if (isLoadingChildrenLoops) { isLoadingChildrenLoops = false; } childrenLoopsEventsData.StartOfLoop8Event.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Puzzle: Logger.Log("Children Loop Puzzle activated."); HandlePuzzle(); SaveStorylineState(); break; default: Logger.LogWarning("Unhandled Children Loop State: " + currentChildrenLoopState); break; } } private void HandleCheckLoadState() { if (IsInitialCutscenePlayed()) { Logger.Print("Try Load Saved State"); TryLoadSavedState(); } else //If started new game for the first time: { Logger.Print("New game started"); PlayInitialCutscene(); SetupPlayer(playerNewGameStartPosition, enableCameraCarMovement: false, enablePlayerController: true, pocketWatchIsObtained: true); UpdateToNextLoopState(); } } private bool IsInitialCutscenePlayed() => GameProgressManager.GetInstance().initialCutscenePlayed; private void PlayInitialCutscene() { Logger.Log("Playing initial cutscene..."); SetInitialCutscenePlayed(true); var gameProgressManager = GameProgressManager.GetInstance(); gameProgressManager.playerControllerShouldBeEnabledOnGameLoad = false; gameProgressManager.playerCameraControllerShouldBeEnabledOnGameLoad = true; } private void SetInitialCutscenePlayed(bool value) => GameProgressManager.GetInstance().initialCutscenePlayed = value; private void SetupPlayer(Transform newPosition, bool enableCameraCarMovement, bool enablePlayerController, bool pocketWatchIsObtained) { var playerManager = PlayerManager.GetInstance(); if (playerManager == null) { Logger.LogError("PlayerManager instance is missing!"); return; } //playerManager.DisablePlayerMovement(); playerManager.playerGameObj.transform.position = newPosition.position; playerManager.playerGameObj.transform.rotation = newPosition.rotation; playerManager.playerGameObj.transform.SetParent(newPosition); playerManager._cameraMovement.cameraCarMovement = enableCameraCarMovement; var gameProgressManager = GameProgressManager.GetInstance(); gameProgressManager.playerControllerShouldBeEnabledOnGameLoad = enablePlayerController; gameProgressManager.PocketWatchIsObtained = pocketWatchIsObtained; InventoryManager.GetInstance().SaveTemporarilyPocketWatchInventoryItemData(true); //Obtained pocket watch so save temporarily. } /// /// Moves to the next loop/puzzle state, if available. /// public void UpdateToNextLoopState() { ChildrenLoopState[] allStates = (ChildrenLoopState[])Enum.GetValues(typeof(ChildrenLoopState)); int currentIndex = Array.IndexOf(allStates, currentChildrenLoopState); if (currentIndex < allStates.Length - 1) { // Move to the next state currentChildrenLoopState = allStates[currentIndex + 1]; UpdateStoryline(); } else { Logger.Log("All Children Loops and the puzzle are complete."); NotifyCompletion(); } } /// /// Attempt to load the saved Children loop state from GameProgressManager. /// private void TryLoadSavedState() { var gameProgressManager = GameProgressManager.GetInstance(); if (gameProgressManager == null) return; if (Enum.TryParse(gameProgressManager.currentStorylineState, out ChildrenLoopState savedState)) { currentChildrenLoopState = savedState; Logger.Log("Loaded Children Loop State from save: " + savedState); UpdateStoryline(); } else { Logger.LogWarning("No valid saved Children Loop state found. Starting at Loop1."); currentChildrenLoopState = ChildrenLoopState.LongHallway; UpdateStoryline(); } // After loading, no longer in a loading phase isLoadingChildrenLoops = false; } /// /// Saves the current Children loop state to GameProgressManager. /// private void SaveStorylineState() { var gameProgressManager = GameProgressManager.GetInstance(); if (gameProgressManager == null) return; gameProgressManager.currentStorylineState = currentChildrenLoopState.ToString(); } /// /// Performs any final logic, then notifies GameManager this section is complete. /// private void NotifyCompletion() { // Let GameManager know this story section (ChildrenLoops) is done GameManager.GetInstance().OnStorySectionComplete(GameManager.StoryState.ChildrenLoops); } /// /// Resets or cleans up player settings if needed. /// private void CleanupPlayerSettings() { var playerManager = PlayerManager.GetInstance(); if (playerManager != null) { // Example: disable or reset player movement or camera // playerManager.DisablePlayerMovement(); } Logger.Log("Cleaned up settings specific to Children Loops."); } // ------------------------ Loop-Specific Handlers ------------------------ private void HandleLoop1() { /* Faint, childlike humming echoes around the corners * They discover torn pieces of a child�s drawing pinned to various spots, * depicting fragments like a clock reading �11:20.� * Picking up the final piece triggers a jumpscare: * a swift silhouette of a small child darts across the hallway intersection, * accompanied by a sharp stinger of eerie music. *The player reassembles the drawing, * which reveals a clue�such as a clock time (�11:20�) or a cryptic phrase (�She won�t stop crying at 11:20�). * If the player sets their watch to 11:20, the hallway flickers, * momentarily transporting them to an earlier moment * where distant cries from baby Emily are heard before abruptly cutting off. * In the Kids� Bedroom, they also find notes �Emily�s cradle� and �Medea�s frustration"*/ } private void HandleLoop2() { // Logic for loop 2 } private void HandleLoop3() { // Logic for loop 3 } private void HandleLoop4() { // Logic for loop 4 } private void HandleLoop5() { // Logic for loop 5 } private void HandleLoop6() { // Logic for loop 6 } private void HandleLoop7() { // Logic for loop 7 } private void HandleLoop8() { // Logic for loop 8 (the final loop before puzzle) } // ------------------------ Puzzle Handler ------------------------ private void HandlePuzzle() { // Activate puzzle elements if (puzzleGameObject != null) { puzzleGameObject.SetActive(true); } // Optionally handle puzzle-solved scenario: // puzzleSolvedEffects.SetActive(true); // if puzzle is solved // Then call UpdateToNextLoopState() or NotifyCompletion() if final } } [Serializable] public class ChildrenLoopsEventsData { public UnityEvent StartOfLongHallwayLeadingToLoops; public UnityEvent StartOfLoop1Event; public UnityEvent StartOfLoop2Event; public UnityEvent StartOfLoop3Event; public UnityEvent StartOfLoop4Event; public UnityEvent StartOfLoop5Event; public UnityEvent StartOfLoop6Event; public UnityEvent StartOfLoop7Event; public UnityEvent StartOfLoop8Event; } [Serializable] public class ChildrenLoopsPuzzlesData { public LightSwitchesPuzzle lightsSwitchesPuzzleInLoop3; public ManageLightSwitchesInRoom ManageLightSwitchesInLoop3; }