using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.SceneManagement; using System; #if UNITY_EDITOR using UnityEditor; #endif using InfallibleCode; [System.Serializable] public class SceneAssetReference { #if UNITY_EDITOR public SceneAsset sceneAsset; #endif [HideInInspector] public string sceneName; public string SceneName { get { #if UNITY_EDITOR if (sceneAsset != null) { sceneName = sceneAsset.name; } #endif return sceneName; } } } [System.Serializable] public class NearbyRoomCategory { public string categoryName; public List nearbyRoomScenes = new List(); } public class RoomTrigger : MonoBehaviour { public int playersCurrentRoomID; public int playersPreviousRoomID; public int roomID; [Header("Hiding Spots")] [SerializeField] private List closetHideBehaviour = new List(); [SerializeField] private List bedHideBehaviour = new List(); [SerializeField] private List roomPatrolPoints = new List(); [Header("Nearby Room Categories")] [SerializeField] public List nearbyRoomCategories = new List(); [SerializeField] public int activeCategoryIndex = 0; [Header("Room Scene Info")] [SerializeField] private List roomChunks = new List(); #if UNITY_EDITOR [SerializeField] private SceneAsset roomSceneAsset; #endif [SerializeField] private string roomSceneName; public string RoomSceneName { get { #if UNITY_EDITOR if (roomSceneAsset != null) { roomSceneName = roomSceneAsset.name; } #endif return roomSceneName; } } private bool playerIsInTrigger; public bool enemyAIIsInTrigger; private bool startExecuted = false; private void Start() { StartCoroutine(AfterGameLoaded()); } IEnumerator AfterGameLoaded() { yield return new WaitUntil(() => LoadManager.GetInstance() != null && !LoadManager.GetInstance().LoadingGame); yield return new WaitUntil(() => RoomManager.GetInstance() != null); AfterLoadUpdate(); } private void AfterLoadUpdate() { if (RoomManager.GetInstance() != null) { RoomManager.GetInstance().RegisterRoomTrigger(this); } GameSaveData loadedData = SaveSlotManager.LoadPlayerData(SaveSlotManager.GetInstance().selectedSaveSlotID); bool categorySet = false; if (loadedData != null && loadedData.sceneSaveData.RoomTriggerData != null) { foreach (var roomTriggerData in loadedData.sceneSaveData.RoomTriggerData) { if (roomTriggerData.roomSceneName == RoomSceneName) { SetActiveCategory(roomTriggerData.activeCategoryIndex); categorySet = true; break; } } } // 🛑 Fallback: Δες αν υπάρχει snapshot από το RoomManager if (!categorySet && RoomManager.GetInstance() != null && RoomManager.GetInstance().roomTriggersSnapshotData != null) { foreach (var snapshot in RoomManager.GetInstance().roomTriggersSnapshotData) { if (snapshot.roomSceneName == RoomSceneName) { SetActiveCategory(snapshot.activeCategoryIndex); Debug.Log($"[RoomTrigger] Fallback: Restored activeCategoryIndex from RoomManager snapshot: {snapshot.activeCategoryIndex}"); break; } } } var pending = RoomManager.GetInstance()?.pendingCategoryChanges? .FirstOrDefault(p => p.roomSceneName == RoomSceneName); if (pending != null) { SetActiveCategory(pending.categoryIndex); UpdateRoomTriggerSnapshot(); RoomManager.GetInstance().pendingCategoryChanges.Remove(pending); Debug.Log($"[RoomTrigger] Applied pending category change ({pending.categoryIndex}) for scene {RoomSceneName}"); } RoomManager.GetInstance().OnRoomsChanged += NearbyRoomsUpdate; startExecuted = true; } private void OnDestroy() { if (RoomManager.GetInstance() != null) RoomManager.GetInstance().OnRoomsChanged -= NearbyRoomsUpdate; if (RoomManager.GetInstance() != null) { RoomManager.GetInstance().UnregisterRoomTrigger(this); } } public void UpdateRoomTriggerSnapshot() { if (RoomManager.GetInstance() == null) return; var existing = RoomManager.GetInstance().roomTriggersSnapshotData.Find( x => x.roomSceneName == RoomSceneName ); if (existing != null) { existing.activeCategoryIndex = activeCategoryIndex; } else { RoomTriggerData newData = new RoomTriggerData { roomSceneName = RoomSceneName, activeCategoryIndex = activeCategoryIndex }; RoomManager.GetInstance().roomTriggersSnapshotData.Add(newData); } } private void NearbyRoomsUpdate() { if (playerIsInTrigger) { SceneLoadWithChunks(); } } public List GetActiveNearbyRooms() { if (nearbyRoomCategories.Count == 0 || activeCategoryIndex < 0 || activeCategoryIndex >= nearbyRoomCategories.Count) return new List(); return nearbyRoomCategories[activeCategoryIndex].nearbyRoomScenes .Where(s => !string.IsNullOrEmpty(s.SceneName)) .Select(s => s.SceneName) .ToList(); } public void SetActiveCategory(int index) { if (index >= 0 && index < nearbyRoomCategories.Count) { activeCategoryIndex = index; RoomManager.GetInstance()?.RoomsChanged(); //UpdateRoomTriggerSnapshot(); if (playerIsInTrigger) { Debug.Log($"[RoomTrigger] Active category changed to: {nearbyRoomCategories[index].categoryName}. Reloading scenes..."); SceneLoadWithChunks(); } } } //public void NextCategory() //{ // if (nearbyRoomCategories.Count == 0) return; // activeCategoryIndex = (activeCategoryIndex + 1) % nearbyRoomCategories.Count; // RoomManager.GetInstance()?.RoomsChanged(); // UpdateRoomTriggerSnapshot(); //} //public void PreviousCategory() //{ // if (nearbyRoomCategories.Count == 0) return; // activeCategoryIndex = (activeCategoryIndex - 1 + nearbyRoomCategories.Count) % nearbyRoomCategories.Count; // RoomManager.GetInstance()?.RoomsChanged(); // UpdateRoomTriggerSnapshot(); //} private IEnumerator DelayedTrigger(Collider other) { yield return new WaitUntil(() => startExecuted); OnTriggerEnter(other); } private void OnTriggerEnter(Collider other) { if (!startExecuted) { StartCoroutine(DelayedTrigger(other)); return; } if (other.CompareTag("Player") && !playerIsInTrigger) { playersCurrentRoomID = roomID; RoomManager.GetInstance()._roomID = roomID; RoomManager.GetInstance()._roomPatrolPoints = roomPatrolPoints; GetCurrentRoomsHideBehaviours(); RoomManager.GetInstance()._nearbyRoomSceneNames = GetActiveNearbyRooms(); SetLastRoomTriggerPlayerEntered(); SceneLoadWithChunks(); playerIsInTrigger = true; } if (other.CompareTag("EnemyAI") && !enemyAIIsInTrigger) { enemyAIIsInTrigger = true; } } private void SceneLoadWithChunks() { if (string.IsNullOrEmpty(RoomSceneName)) return; List activeNearbyScenes = GetActiveNearbyRooms(); DynamicSceneManager.GetInstance().RetainScene(RoomSceneName); //DynamicSceneManager.GetInstance().EnableChunks(roomChunks, RoomSceneName); foreach (string nearbySceneName in activeNearbyScenes) { if (!DynamicSceneManager.GetInstance().IsSceneLoaded(nearbySceneName)) { DynamicSceneManager.GetInstance().RetainScene(nearbySceneName); } } HashSet scenesToKeepLoaded = new HashSet(); scenesToKeepLoaded.Add(RoomSceneName); if (RoomManager.GetInstance() != null) { if (RoomManager.GetInstance().necessarySceneNamesToKeepLoaded != null) scenesToKeepLoaded.UnionWith(RoomManager.GetInstance().necessarySceneNamesToKeepLoaded); if (RoomManager.GetInstance()._nearbyRoomSceneNames != null) scenesToKeepLoaded.UnionWith(RoomManager.GetInstance()._nearbyRoomSceneNames); } for (int i = 0; i < SceneManager.sceneCount; i++) { Scene loadedScene = SceneManager.GetSceneAt(i); if (string.IsNullOrEmpty(loadedScene.name)) continue; if (!scenesToKeepLoaded.Contains(loadedScene.name)) { DynamicSceneManager.GetInstance()?.UnloadSceneAsync(loadedScene.name); } } } private void OnTriggerExit(Collider other) { if (other.CompareTag("Player") && playerIsInTrigger) { playersPreviousRoomID = roomID; ClearCurrentRoomsHiddingSpots(); ClearRoomDataTemporary(); playerIsInTrigger = false; } if (other.CompareTag("EnemyAI") && enemyAIIsInTrigger) { enemyAIIsInTrigger = false; } } public void GetCurrentRoomsHideBehaviours() { foreach (ClosetHideBehaviour closet in closetHideBehaviour) { RoomManager.GetInstance().closetHideBehaviour.Add(closet); } foreach (BedHideBehaviourBase bed in bedHideBehaviour) { RoomManager.GetInstance().bedHideBehaviour.Add(bed); } } public List GetPatrolPoints() { return roomPatrolPoints; } public void SetLastRoomTriggerPlayerEntered() { RoomManager.GetInstance().LastRoomTriggerPlayerEntered = this; } private void ClearRoomDataTemporary() { RoomManager.GetInstance().closetHideBehaviour.Clear(); RoomManager.GetInstance().bedHideBehaviour.Clear(); RoomManager.GetInstance().LastRoomTriggerPlayerEntered = null; } public void ClearNearbySceneNames() { RoomManager.GetInstance()._nearbyRoomSceneNames.Clear(); } public void ClearCurrentRoomsHiddingSpots() { RoomManager.GetInstance().closetHideBehaviour.Clear(); RoomManager.GetInstance().bedHideBehaviour.Clear(); } public List GetNearbySceneNames() { List nearbyScenes = new List(); foreach (NearbyRoomCategory category in nearbyRoomCategories) { nearbyScenes.AddRange(category.nearbyRoomScenes.Select(scene => scene.SceneName)); } return nearbyScenes; } }