Files
HauntedBloodlines/Assets/Scripts/Story/RoomTrigger.cs
2025-05-29 22:31:40 +03:00

381 lines
11 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<SceneAssetReference> nearbyRoomScenes = new List<SceneAssetReference>();
}
public class RoomTrigger : MonoBehaviour
{
public int playersCurrentRoomID;
public int playersPreviousRoomID;
public int roomID;
[Header("Hiding Spots")]
[SerializeField] private List<ClosetHideBehaviour> closetHideBehaviour = new List<ClosetHideBehaviour>();
[SerializeField] private List<BedHideBehaviourBase> bedHideBehaviour = new List<BedHideBehaviourBase>();
[SerializeField] private List<Transform> roomPatrolPoints = new List<Transform>();
[Header("Nearby Room Categories")]
[SerializeField] public List<NearbyRoomCategory> nearbyRoomCategories = new List<NearbyRoomCategory>();
[SerializeField] public int activeCategoryIndex = 0;
[Header("Room Scene Info")]
[SerializeField] private List<GameObject> roomChunks = new List<GameObject>();
#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<string> GetActiveNearbyRooms()
{
if (nearbyRoomCategories.Count == 0 || activeCategoryIndex < 0 || activeCategoryIndex >= nearbyRoomCategories.Count)
return new List<string>();
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<string> 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<string> scenesToKeepLoaded = new HashSet<string>();
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<Transform> 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<string> GetNearbySceneNames()
{
List<string> nearbyScenes = new List<string>();
foreach (NearbyRoomCategory category in nearbyRoomCategories)
{
nearbyScenes.AddRange(category.nearbyRoomScenes.Select(scene => scene.SceneName));
}
return nearbyScenes;
}
}