529 lines
20 KiB
C#
529 lines
20 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using InfallibleCode;
|
|
using UnityEngine.AI;
|
|
using UnityEngine.Playables;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
public class PatrolManager : MonoBehaviour
|
|
{
|
|
private static PatrolManager _instance;
|
|
|
|
public static PatrolManager GetInstance() { return _instance; }
|
|
|
|
[SerializeField] public List<Transform> DefinedPathPatrolPoints;
|
|
[SerializeField] public List<Transform> NearbyRoomPatrolPoints;
|
|
[SerializeField] public List<Transform> HidePatrolPoints;
|
|
[SerializeField] public List<ClosetHideBehaviour> ClosetHideBehaviourEnemyShouldPatrol;
|
|
[SerializeField] public RoomTrigger lastRoomTriggerEnemySeenPlayer;
|
|
//OPEN WHEN SCRIPTS ARE MADE!!!!
|
|
//[SerializeField] public List<TableHideBehaviour> TableHideBehaviourEnemyShouldPatrol;
|
|
[SerializeField] public List<BedHideBehaviourBase> BedHideBehaviourEnemyShouldPatrol;
|
|
|
|
public Transform takeOutFromHidingSpotPosition;
|
|
public ClosetHideBehaviour closetHideBehaviourPlayerIsHiding;
|
|
public BedHideBehaviourBase bedHideBehaviourPlayerIsHiding;
|
|
|
|
public PlayableDirector medeasCurrentPlayableDirector;
|
|
|
|
[SerializeField] public bool _canChangePoint = true;
|
|
/*[SerializeField] private */
|
|
public int _destinationPoint;
|
|
public bool CanPatrol;
|
|
public bool CanPatrolNearbyRooms;
|
|
public bool CanPatrolAroundTheHouse; //closest patrol point
|
|
void Awake()
|
|
{
|
|
if (!_instance)
|
|
{
|
|
_instance = this;
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (CanPatrol)
|
|
{
|
|
isPatroling();
|
|
//UpdatePath();
|
|
}
|
|
}
|
|
|
|
// I want to create a switch where i will put the rooms and every room will have its own transform points
|
|
public enum Rute
|
|
{
|
|
DefinedPath,
|
|
SearchingForHiddenPlayerPath,
|
|
NearbyRoomsPath,
|
|
GoesToTakeOutPlayerFromHiddingSpotPath,
|
|
LostPlayerPath
|
|
|
|
}
|
|
|
|
public Rute content = Rute.DefinedPath;
|
|
public void isPatroling()
|
|
{
|
|
switch (content)
|
|
{
|
|
case Rute.DefinedPath:
|
|
|
|
Patrol(DefinedPathPatrolPoints);
|
|
|
|
break;
|
|
|
|
case Rute.SearchingForHiddenPlayerPath:
|
|
|
|
//Goes to the room of the player to search
|
|
//in the hidding spots except the players
|
|
//and then leaves for nearby rooms AKA LostPlayerPath
|
|
PatrolHidingSpots();
|
|
break;
|
|
case Rute.NearbyRoomsPath:
|
|
if (_destinationPoint > NearbyRoomPatrolPoints.Count -1)
|
|
{
|
|
//MedeaDemonicEnemyBehaviour.GetInstance()._medeaAI.isStopped = true;
|
|
print("Should go to DefinedPath after checked all nearby rooms");
|
|
_destinationPoint = 0;
|
|
content = Rute.DefinedPath;
|
|
MedeaDemonicEnemyBehaviour.GetInstance().state = MedeaDemonicEnemyBehaviour.medeaState.Patroling;
|
|
}
|
|
PatrolNearbyRooms(NearbyRoomPatrolPoints);
|
|
break;
|
|
case Rute.GoesToTakeOutPlayerFromHiddingSpotPath:
|
|
//Closest Patrol point to the player
|
|
//Go to transform to uncover the player
|
|
TakePlayerOutOfHidingSpot();
|
|
break;
|
|
|
|
case Rute.LostPlayerPath:
|
|
|
|
//Gets the players position and patrols in the defined
|
|
//path starting from the nearest point
|
|
|
|
//OPEN THIS IS YOU WANT TO DESPAWN HER 5 MIN AFTER SHE LOST THE PLAYER
|
|
//MedeaDemonicEnemyBehaviour.GetInstance().StartMedeaDespawn();
|
|
break;
|
|
}
|
|
}
|
|
|
|
IEnumerator WaitForNext()
|
|
{
|
|
Debug.Log("Enemy Is Waiting");
|
|
yield return new WaitForSeconds(5f);
|
|
Debug.Log("Enemy can move again now");
|
|
MedeaDemonicEnemyBehaviour.GetInstance()._medeaAI.isStopped = false;
|
|
_canChangePoint = true;
|
|
#region Animation
|
|
if (MedeaDemonicEnemyBehaviour.GetInstance().medeaAnimator.GetBool("IsLookingAround")) //If is looking around:
|
|
{
|
|
MedeaDemonicEnemyBehaviour.GetInstance().medeaAnimator.SetBool("IsLookingAround", false);
|
|
}
|
|
#endregion)
|
|
//StopAllCoroutines();
|
|
}
|
|
|
|
void Patrol(List<Transform> point)
|
|
{
|
|
if (_canChangePoint)
|
|
{
|
|
if (!MedeaDemonicEnemyBehaviour.GetInstance()._medeaAI.pathPending &&
|
|
MedeaDemonicEnemyBehaviour.GetInstance()._medeaAI.remainingDistance < 0.25)
|
|
{
|
|
#region Play animation
|
|
MedeaDemonicEnemyBehaviour.GetInstance().medeaAnimator.SetBool("IsLookingAround", true);
|
|
#endregion
|
|
|
|
MedeaDemonicEnemyBehaviour.GetInstance()._medeaAI.isStopped = true;
|
|
MedeaDemonicEnemyBehaviour.GetInstance()._medeaAI.destination = point[_destinationPoint].position;
|
|
_canChangePoint = false;
|
|
_destinationPoint = (_destinationPoint + 1) % point.Count;
|
|
StartCoroutine(WaitForNext());
|
|
}
|
|
}
|
|
}
|
|
|
|
void PatrolNearbyRooms(List<Transform> point)
|
|
{
|
|
if (_canChangePoint)
|
|
{
|
|
if (!MedeaDemonicEnemyBehaviour.GetInstance()._medeaAI.pathPending &&
|
|
MedeaDemonicEnemyBehaviour.GetInstance()._medeaAI.remainingDistance < 0.25)
|
|
{
|
|
#region Play animation
|
|
MedeaDemonicEnemyBehaviour.GetInstance().medeaAnimator.SetBool("IsLookingAround", true);
|
|
#endregion
|
|
|
|
MedeaDemonicEnemyBehaviour.GetInstance()._medeaAI.isStopped = true;
|
|
MedeaDemonicEnemyBehaviour.GetInstance()._medeaAI.destination = point[_destinationPoint].position;
|
|
_canChangePoint = false;
|
|
_destinationPoint = _destinationPoint + 1;
|
|
StartCoroutine(WaitForNext());
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates Enemy's take out of hiding spot.
|
|
/// </summary>
|
|
void TakePlayerOutOfHidingSpot()
|
|
{
|
|
print("Take player out bitch");
|
|
MedeaDemonicEnemyBehaviour.GetInstance()._medeaAI.destination = takeOutFromHidingSpotPosition.position;
|
|
CanPatrol = true; // 13.8.24 Yiannis & Maya Added
|
|
|
|
if (!MedeaDemonicEnemyBehaviour.GetInstance()._medeaAI.pathPending &&
|
|
MedeaDemonicEnemyBehaviour.GetInstance()._medeaAI.remainingDistance < 0.5)
|
|
{
|
|
if (HideManager.GetInstance().InCloset)
|
|
{
|
|
StartCoroutine(UpdateSmoothlyPatrolHidingSpotMedeaRotation(2f, takeOutFromHidingSpotPosition));
|
|
print("Reached hiding spot destination for InCloset");
|
|
closetHideBehaviourPlayerIsHiding.PlayEnemyKillPlayerInClosetCutscene();
|
|
}
|
|
else if (HideManager.GetInstance().UnderBed)
|
|
{
|
|
print("Reached hiding spot destination for UnderBed");
|
|
if (HideManager.GetInstance().isInBedRightSide)
|
|
{
|
|
StartCoroutine(UpdateSmoothlyPatrolHidingSpotMedeaRotation(2f, takeOutFromHidingSpotPosition));
|
|
bedHideBehaviourPlayerIsHiding.PlayEnemyBedSearchCutscene();
|
|
}
|
|
else
|
|
{
|
|
StartCoroutine(UpdateSmoothlyPatrolHidingSpotMedeaRotation(2f, takeOutFromHidingSpotPosition));
|
|
bedHideBehaviourPlayerIsHiding.PlayEnemyBedSearchCutscene();
|
|
}
|
|
}
|
|
else if (HideManager.GetInstance().UnderTable)
|
|
{
|
|
print("Reached hiding spot destination for UnderTable");
|
|
//Play necessary kill cutscene.
|
|
}
|
|
|
|
CanPatrol = false;
|
|
_canChangePoint = false;
|
|
}
|
|
}
|
|
|
|
public void UpdatePatrolHidingSpots()
|
|
{
|
|
ClosetHideBehaviourEnemyShouldPatrol.Clear();
|
|
BedHideBehaviourEnemyShouldPatrol.Clear();
|
|
HidePatrolPoints.Clear();
|
|
|
|
|
|
print("Update patrol hiding spots");
|
|
|
|
foreach (var closetHideBehaviour in RoomManager.GetInstance().closetHideBehaviour)
|
|
{
|
|
if (!closetHideBehaviour.playerIsHidingInThisCloset)
|
|
{
|
|
ClosetHideBehaviourEnemyShouldPatrol.Add(closetHideBehaviour);
|
|
HidePatrolPoints.Add(closetHideBehaviour.enemySearchPosition);
|
|
}
|
|
else //If player is hiding in this closet:
|
|
{
|
|
//if (HideManager.GetInstance().InCloset)
|
|
//{
|
|
if (closetHideBehaviour.lightSwitch != null)
|
|
{
|
|
HideManager.GetInstance().currentClosetLightSwitch = closetHideBehaviour.lightSwitch;
|
|
}
|
|
else
|
|
{
|
|
HideManager.GetInstance().currentClosetLightSwitch = null;
|
|
}
|
|
//}
|
|
}
|
|
}
|
|
|
|
foreach (var bedHideBehaviour in RoomManager.GetInstance().bedHideBehaviour)
|
|
{
|
|
if (!bedHideBehaviour.playerIsHidingUnderBed)
|
|
{
|
|
if (bedHideBehaviour.isInRightSide)
|
|
{
|
|
BedHideBehaviourEnemyShouldPatrol.Add(bedHideBehaviour);
|
|
HidePatrolPoints.Add(bedHideBehaviour.enemySearchPositionRight);
|
|
print("Added BedHideBehaviourEnemyShouldPatrol RIGHT SIDE");
|
|
}
|
|
else
|
|
{
|
|
BedHideBehaviourEnemyShouldPatrol.Add(bedHideBehaviour);
|
|
HidePatrolPoints.Add(bedHideBehaviour.enemySearchPositionLeft);
|
|
print("Added BedHideBehaviourEnemyShouldPatrol LEFT SIDE");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void UpdatePatrolHidingSpotMedeaRotation()
|
|
{
|
|
if (_destinationPoint - 1 != -1)
|
|
{
|
|
//Vector3 dir = HidePatrolPoints[_destinationPoint - 1].position - MedeaDemonicEnemyBehaviour.GetInstance()._medea.position;
|
|
//dir.y = 0; // This allows the object to only rotate on its y axis
|
|
//Quaternion rot = Quaternion.LookRotation(dir.normalized, Vector3.up); // Use dir.normalized to ensure proper alignment
|
|
//float rotationSpeed = 2f;
|
|
|
|
//// Set Y rotation separately
|
|
//rot = Quaternion.Euler(0, rot.eulerAngles.y, 0); // Keep only the Y rotation
|
|
//MedeaDemonicEnemyBehaviour.GetInstance()._medea.localRotation = Quaternion.Lerp(MedeaDemonicEnemyBehaviour.GetInstance()._medea.localRotation, rot, rotationSpeed * Time.deltaTime);
|
|
|
|
|
|
// Get the direction to the destination
|
|
Vector3 direction = (MedeaDemonicEnemyBehaviour.GetInstance()._medeaAI.destination - transform.position).normalized;
|
|
|
|
// Calculate the rotation to face the destination
|
|
Quaternion lookRotation = Quaternion.LookRotation(MedeaDemonicEnemyBehaviour.GetInstance()._medeaAI.destination);
|
|
|
|
// Apply the rotation to the agent
|
|
MedeaDemonicEnemyBehaviour.GetInstance()._medea.rotation = HidePatrolPoints[_destinationPoint - 1].rotation;
|
|
}
|
|
}
|
|
|
|
IEnumerator UpdateSmoothlyPatrolHidingSpotMedeaRotation(float rotationSpeed, Transform targetDestination)
|
|
{
|
|
float timeElapsed = 0;
|
|
float lerpDuration = 1/ rotationSpeed;
|
|
while (timeElapsed < lerpDuration)
|
|
{
|
|
// Calculate the target rotation based on the current destination point
|
|
Quaternion targetRotation = targetDestination.rotation;
|
|
|
|
// Smoothly interpolate between the current rotation and the target rotation
|
|
MedeaDemonicEnemyBehaviour.GetInstance()._medea.transform.rotation = Quaternion.Slerp(MedeaDemonicEnemyBehaviour.GetInstance()._medea.transform.rotation, targetRotation, timeElapsed / lerpDuration);
|
|
timeElapsed += Time.deltaTime;
|
|
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
void PatrolHidingSpots(/*List<Transform> point*/)
|
|
{
|
|
//_destinationPoint = 0;
|
|
//UpdatePatrolHidingSpotMedeaRotation();
|
|
if (_canChangePoint)
|
|
{
|
|
#region Check if needed
|
|
//if (ClosetHideBehaviourEnemyShouldPatrol != null)
|
|
//{
|
|
// MedeaDemonicEnemyBehaviour.GetInstance()._medeaAI.destination = ClosetHideBehaviourEnemyShouldPatrol[_destinationPoint].enemySearchPosition.position;
|
|
//}
|
|
////else if (TableHideBehaviourEnemyShouldPatrol)
|
|
////{
|
|
|
|
////}
|
|
////else if (BedHideBehaviourEnemyShouldPatrol)
|
|
////{
|
|
|
|
////}
|
|
///
|
|
#endregion
|
|
if (_destinationPoint < HidePatrolPoints.Count)
|
|
{
|
|
MedeaDemonicEnemyBehaviour.GetInstance()._medeaAI.destination = HidePatrolPoints[_destinationPoint].position;
|
|
|
|
if (!MedeaDemonicEnemyBehaviour.GetInstance()._medeaAI.pathPending &&
|
|
MedeaDemonicEnemyBehaviour.GetInstance()._medeaAI.remainingDistance < 0.1)
|
|
{
|
|
#region Check if needed
|
|
//if (ClosetHideBehaviourEnemyShouldPatrol != null)
|
|
//{
|
|
// foreach (var closetHideBehaviourEnemyShouldPatrol in ClosetHideBehaviourEnemyShouldPatrol)
|
|
// {
|
|
// ClosetHideBehaviourEnemyShouldPatrol[_destinationPoint].PlayEnemyClosetSearchCutscene();
|
|
// }
|
|
|
|
//}
|
|
////else if (TableHideBehaviourEnemyShouldPatrol)
|
|
////{
|
|
|
|
////}
|
|
////else if (BedHideBehaviourEnemyShouldPatrol)
|
|
////{
|
|
|
|
////}
|
|
///
|
|
#endregion
|
|
StartCoroutine(UpdateSmoothlyPatrolHidingSpotMedeaRotation(2f, HidePatrolPoints[_destinationPoint]));
|
|
print("Play Enemy Closet Search Cutscene!");
|
|
#region Closet
|
|
HidePatrolPoints[_destinationPoint].parent.transform.parent.TryGetComponent<ClosetHideBehaviour>(out ClosetHideBehaviour _closetHideBehaviour);
|
|
if (_closetHideBehaviour != null)
|
|
{
|
|
_closetHideBehaviour.PlayEnemyClosetSearchCutscene();
|
|
}
|
|
#endregion
|
|
|
|
#region Bed
|
|
HidePatrolPoints[_destinationPoint].parent.transform.parent.transform.parent.TryGetComponent<BedHideBehaviourBase>(out BedHideBehaviourBase _bedHideBehaviour);
|
|
if (_bedHideBehaviour != null)
|
|
{
|
|
_bedHideBehaviour.PlayEnemyBedSearchCutscene();
|
|
}
|
|
#endregion
|
|
|
|
_destinationPoint = _destinationPoint +1;
|
|
_canChangePoint = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_destinationPoint = 0;
|
|
content = Rute.NearbyRoomsPath;
|
|
}
|
|
}
|
|
|
|
if (HideManager.GetInstance().currentClosetLightSwitch != null && HideManager.GetInstance().InCloset && RoomManager.GetInstance().LastRoomTriggerPlayerEntered.enemyAIIsInTrigger
|
|
&& HideManager.GetInstance().lightSwitchTimerIsRunning == false)
|
|
{
|
|
HideManager.GetInstance().StartClosetCoroutineTimer();
|
|
// MedeaDemonicEnemyBehaviour.GetInstance().state = MedeaDemonicEnemyBehaviour.medeaState.TakingOutPlayerFromHiddingSpot;
|
|
|
|
}
|
|
}
|
|
|
|
public void UpdateTakeOutPlayerSpot()
|
|
{
|
|
if (HideManager.GetInstance().InCloset)
|
|
{
|
|
foreach (var _closetHideBehaviour in RoomManager.GetInstance().closetHideBehaviour)
|
|
{
|
|
if (_closetHideBehaviour.playerIsHidingInThisCloset)
|
|
{
|
|
closetHideBehaviourPlayerIsHiding = _closetHideBehaviour;
|
|
takeOutFromHidingSpotPosition = _closetHideBehaviour.enemySearchPosition;
|
|
}
|
|
}
|
|
}
|
|
else if (HideManager.GetInstance().UnderBed)
|
|
{
|
|
foreach (var _bedHideBehaviour in RoomManager.GetInstance().bedHideBehaviour)
|
|
{
|
|
if (_bedHideBehaviour.playerIsHidingUnderBed)
|
|
{
|
|
bedHideBehaviourPlayerIsHiding = _bedHideBehaviour;
|
|
if (_bedHideBehaviour.isInRightSide)
|
|
{
|
|
takeOutFromHidingSpotPosition = _bedHideBehaviour.enemySearchPositionRight;
|
|
}
|
|
else
|
|
{
|
|
takeOutFromHidingSpotPosition = _bedHideBehaviour.enemySearchPositionLeft;
|
|
}
|
|
}
|
|
}
|
|
//Implementation for bed.
|
|
}
|
|
else if (HideManager.GetInstance().UnderTable)
|
|
{
|
|
//Implementation for table.
|
|
}
|
|
}
|
|
|
|
public void SetNearbyRoomsPatrolPoints()
|
|
{
|
|
NearbyRoomPatrolPoints.Clear();
|
|
lastRoomTriggerEnemySeenPlayer = RoomManager.GetInstance().LastRoomTriggerPlayerEntered;
|
|
|
|
if (lastRoomTriggerEnemySeenPlayer == null)
|
|
{
|
|
Debug.LogWarning("LastRoomTriggerPlayerEntered is null. Cannot set nearby room patrol points.");
|
|
return;
|
|
}
|
|
|
|
// Use _nearbyRoomSceneNames from RoomManager
|
|
foreach (string nearbySceneName in RoomManager.GetInstance()._nearbyRoomSceneNames)
|
|
{
|
|
List<Transform> patrolPoints = GetPatrolPointsForScene(nearbySceneName);
|
|
|
|
if (patrolPoints != null)
|
|
{
|
|
NearbyRoomPatrolPoints.AddRange(patrolPoints);
|
|
}
|
|
}
|
|
|
|
Debug.Log($"Nearby patrol points set. Found {NearbyRoomPatrolPoints.Count} patrol points.");
|
|
}
|
|
|
|
|
|
public List<string> GetNearbySceneNames()
|
|
{
|
|
List<string> nearbyScenes = new List<string>();
|
|
|
|
// Add manually defined nearby scenes
|
|
foreach (string sceneName in RoomManager.GetInstance()._nearbyRoomSceneNames) // Assume nearbyRoomSceneNames is a string list
|
|
{
|
|
nearbyScenes.Add(sceneName);
|
|
}
|
|
|
|
return nearbyScenes;
|
|
}
|
|
|
|
public List<Transform> GetPatrolPointsForScene(string sceneName)
|
|
{
|
|
List<Transform> patrolPoints = new List<Transform>();
|
|
|
|
if (!DynamicSceneManager.GetInstance().IsSceneLoaded(sceneName))
|
|
{
|
|
Debug.LogWarning($"Scene {sceneName} is not loaded. Cannot retrieve patrol points.");
|
|
return patrolPoints;
|
|
}
|
|
|
|
// Find RoomTriggers in the scene and collect their patrol points
|
|
Scene scene = SceneManager.GetSceneByName(sceneName);
|
|
foreach (GameObject rootObject in scene.GetRootGameObjects())
|
|
{
|
|
RoomTrigger roomTrigger = rootObject.GetComponentInChildren<RoomTrigger>();
|
|
if (roomTrigger != null)
|
|
{
|
|
patrolPoints.AddRange(roomTrigger.GetPatrolPoints());
|
|
}
|
|
}
|
|
|
|
return patrolPoints;
|
|
}
|
|
|
|
//public void SetNearbyRoomsPatrolPoints()
|
|
//{
|
|
// NearbyRoomPatrolPoints.Clear();
|
|
// lastRoomTriggerEnemySeenPlayer = RoomManager.GetInstance().LastRoomTriggerPlayerEntered;
|
|
// foreach (RoomTrigger nearbyRoomTrigger in lastRoomTriggerEnemySeenPlayer.nearbyRoomTriggers)
|
|
// {
|
|
// NearbyRoomPatrolPoints.Add(nearbyRoomTrigger.transform);
|
|
// }
|
|
//}
|
|
|
|
|
|
|
|
//Transform CalculateHiddingSpotPatrolPoint()
|
|
//{
|
|
// if (MedeaDemonicEnemyBehaviour.GetInstance().IsPlayerHidden())
|
|
// {
|
|
// List<Transform> playersHiddingSpots = RoomManager.GetInstance()._roomHiddingSpots;
|
|
|
|
// Transform closestSpot = null;
|
|
// float closestDistance = Mathf.Infinity;
|
|
|
|
// foreach (Transform spot in playersHiddingSpots)
|
|
// {
|
|
// float distance = Vector3.Distance(PlayerManager.GetInstance().transform.position, spot.position);
|
|
|
|
// if (distance < closestDistance)
|
|
// {
|
|
// closestDistance = distance;
|
|
// closestSpot = spot;
|
|
// }
|
|
// }
|
|
|
|
// return closestSpot;
|
|
|
|
// }
|
|
|
|
// return null;
|
|
//}
|
|
}
|
|
|