using UnityEngine; using System; using System.Collections; using UnityEngine.Events; public class ChildrenLoopsDemoManager : 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 isLoadingChildrenLoopsDemo; [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 ChildrenLoopsDemoEventsData childrenLoopsDemoEventsData; public ChildrenLoopsDemoPuzzlesData childrenLoopsDemoPuzzlesData; // 1. Define the loop states (8 loops + 1 puzzle) public enum ChildrenLoopState { CheckLoad, LongHallwayBeforeMirrorLibrary, MirrorLibrary, AfterMirrorLibrarySolution, LongHallwayAfterMirrorLibrary, Loop0, Loop1_BeforePocketWatchObtained, Loop1_AfterPocketWatchObtained, Loop1_AfterDinnerScene, Loop2, Loop3, Loop4, Loop5, Loop6, Loop6B, Loop7, Loop8, Loop9, Loop9B, Puzzle } // Current loop state public ChildrenLoopState currentChildrenLoopState = ChildrenLoopState.CheckLoad; private void Awake() { // Assign this manager to GameManager so it can be activated/deactivated appropriately if (GameManager.GetInstance() != null) { GameManager.GetInstance().childrenLoopsDemoManager = this; } // If we are loading a saved game, mark accordingly if (LoadManager.GetInstance() != null && LoadManager.GetInstance().LoadingGame) { isLoadingChildrenLoopsDemo = true; } } public void Activate() { Debug.Log("Children Loops Manager Activated: Initializing Children Loops."); //TryLoadSavedState(); UpdateStoryline(); } public void Deactivate() { Debug.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.LongHallwayBeforeMirrorLibrary: Debug.Log("Children Loop Long Hallway Before Mirror Library activated."); if (isLoadingChildrenLoopsDemo) { isLoadingChildrenLoopsDemo = false; } childrenLoopsDemoEventsData.StartOfLongHallwayBeforeMirrorLibraryEvent.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.MirrorLibrary: Debug.Log("Children Loop Mirror Library activated."); if (isLoadingChildrenLoopsDemo) { isLoadingChildrenLoopsDemo = false; } childrenLoopsDemoEventsData.StartOfMirrorLibraryEvent.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.AfterMirrorLibrarySolution: Debug.Log("Children Loop After Mirror Library Solution activated."); if (isLoadingChildrenLoopsDemo) { isLoadingChildrenLoopsDemo = false; } childrenLoopsDemoEventsData.AfterMirrorLibraryPuzzleSolutionEvent.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.LongHallwayAfterMirrorLibrary: Debug.Log("Children Loop Long Hallway After Mirror Library activated."); if (isLoadingChildrenLoopsDemo) { isLoadingChildrenLoopsDemo = false; } childrenLoopsDemoEventsData.StartOfLongHallwayAfterMirrorLibraryEvent.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Loop0: Debug.Log("Children Loop 0 activated."); if (isLoadingChildrenLoopsDemo) { isLoadingChildrenLoopsDemo = false; } childrenLoopsDemoEventsData.StartOfLoop0Event.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Loop1_BeforePocketWatchObtained: Debug.Log("Children Loop1_BeforePocketWatchObtained activated."); if (isLoadingChildrenLoopsDemo) { isLoadingChildrenLoopsDemo = false; } childrenLoopsDemoEventsData.StartOfLoop1Event.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Loop1_AfterPocketWatchObtained: Debug.Log("Children Loop1_AfterPocketWatchObtained activated."); if (isLoadingChildrenLoopsDemo) { childrenLoopsDemoEventsData.Loop1AfterPocketWatchObtainedEvent.Invoke(); isLoadingChildrenLoopsDemo = false; } SaveStorylineState(); break; case ChildrenLoopState.Loop1_AfterDinnerScene: Debug.Log("Children Loop1_AfterDinnerScene activated."); if (isLoadingChildrenLoopsDemo) { // childrenLoopsDemoEventsData.Loop1AfterDinnerSceneEvent.Invoke(); isLoadingChildrenLoopsDemo = false; } SaveStorylineState(); break; case ChildrenLoopState.Loop2: Debug.Log("Children Loop 2 activated."); if (isLoadingChildrenLoopsDemo) { isLoadingChildrenLoopsDemo = false; } childrenLoopsDemoEventsData.StartOfLoop2Event.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Loop3: Debug.Log("Children Loop 3 activated."); if (isLoadingChildrenLoopsDemo) { isLoadingChildrenLoopsDemo = false; } //#region Light Switches Puzzle Related: //foreach (var lightSwitch in childrenLoopsDemoPuzzlesData.ManageLightSwitchesInLoop3.lightSwitch) //{ // lightSwitch.onLightSwitchTurnedOn += childrenLoopsDemoPuzzlesData.lightsSwitchesPuzzleInLoop3.CheckPuzzleCombination; // lightSwitch.onLightSwitchTurnedOff += childrenLoopsDemoPuzzlesData.lightsSwitchesPuzzleInLoop3.CheckPuzzleCombination; //} ////YOU NEED TO LATER UNSUBSCRIBE THE LIGHT SWITCHES! //#endregion childrenLoopsDemoEventsData.StartOfLoop3Event.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Loop4: Debug.Log("Children Loop 4 activated."); if (isLoadingChildrenLoopsDemo) { isLoadingChildrenLoopsDemo = false; } childrenLoopsDemoEventsData.StartOfLoop4Event.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Loop5: Debug.Log("Children Loop 5 activated."); if (isLoadingChildrenLoopsDemo) { isLoadingChildrenLoopsDemo = false; } childrenLoopsDemoEventsData.StartOfLoop5Event.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Loop6: Debug.Log("Children Loop 6 activated."); if (isLoadingChildrenLoopsDemo) { isLoadingChildrenLoopsDemo = false; } childrenLoopsDemoEventsData.StartOfLoop6Event.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Loop6B: Debug.Log("Children Loop 6 B activated."); if (isLoadingChildrenLoopsDemo) { isLoadingChildrenLoopsDemo = false; } childrenLoopsDemoEventsData.StartOfLoop6BEvent.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Loop7: Debug.Log("Children Loop 7 activated."); if (isLoadingChildrenLoopsDemo) { isLoadingChildrenLoopsDemo = false; } childrenLoopsDemoEventsData.StartOfLoop7Event.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Loop8: Debug.Log("Children Loop 8 activated (final loop before puzzle)."); if (isLoadingChildrenLoopsDemo) { isLoadingChildrenLoopsDemo = false; } childrenLoopsDemoEventsData.StartOfLoop8Event.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Loop9: Debug.Log("Children Loop 9 activated (final loop before puzzle)."); if (isLoadingChildrenLoopsDemo) { isLoadingChildrenLoopsDemo = false; } childrenLoopsDemoEventsData.StartOfLoop9Event.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Loop9B: Debug.Log("Children Loop 9 B activated (final loop before puzzle)."); if (isLoadingChildrenLoopsDemo) { isLoadingChildrenLoopsDemo = false; } childrenLoopsDemoEventsData.StartOfLoop9BEvent.Invoke(); SaveStorylineState(); break; case ChildrenLoopState.Puzzle: Debug.Log("Children Loop Puzzle activated."); HandlePuzzle(); SaveStorylineState(); break; default: Debug.LogWarning("Unhandled Children Loop State: " + currentChildrenLoopState); break; } } private void HandleCheckLoadState() { if (IsInitialCutscenePlayed()) { print("Try Load Saved State"); TryLoadSavedState(); } else //If started new game for the first time: { print("New game started"); PlayInitialCutscene(); SetupPlayer(playerNewGameStartPosition, enableCameraCarMovement: false, enablePlayerController: true, pocketWatchIsObtained: false); UpdateToNextStorylineState(); } } private bool IsInitialCutscenePlayed() => GameProgressManager.GetInstance().initialCutscenePlayed; private void PlayInitialCutscene() { Debug.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) { Debug.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 UpdateToNextStorylineState() { 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 { Debug.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; Debug.Log("Loaded Children Loop State from save: " + savedState); UpdateStoryline(); } else { Debug.LogWarning("No valid saved Children Loop state found. Starting at Long Hallway Before Mirror Library."); currentChildrenLoopState = ChildrenLoopState.LongHallwayBeforeMirrorLibrary; UpdateStoryline(); } // After loading, no longer in a loading phase isLoadingChildrenLoopsDemo = 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(); } Debug.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 ChildrenLoopsDemoEventsData { public UnityEvent StartOfLongHallwayBeforeMirrorLibraryEvent; public UnityEvent StartOfMirrorLibraryEvent; public UnityEvent AfterMirrorLibraryPuzzleSolutionEvent; public UnityEvent StartOfLongHallwayAfterMirrorLibraryEvent; public UnityEvent StartOfLoop0Event; public UnityEvent StartOfLoop1Event; public UnityEvent Loop1AfterPocketWatchObtainedEvent; public UnityEvent Loop1AfterDinnerSceneEvent; public UnityEvent StartOfLoop2Event; public UnityEvent StartOfLoop3Event; public UnityEvent StartOfLoop4Event; public UnityEvent StartOfLoop5Event; public UnityEvent StartOfLoop6Event; public UnityEvent StartOfLoop6BEvent; public UnityEvent StartOfLoop7Event; public UnityEvent StartOfLoop8Event; public UnityEvent StartOfLoop9Event; public UnityEvent StartOfLoop9BEvent; } [Serializable] public class ChildrenLoopsDemoPuzzlesData { public ManageWindowsInRoom ManageWindowsInMainHall; public LightSwitchesPuzzle lightsSwitchesPuzzleInLoop3; public ManageLightSwitchesInRoom ManageLightSwitchesInLoop3; }