381 lines
11 KiB
C#
381 lines
11 KiB
C#
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;
|
||
}
|
||
}
|