using Cinemachine; using System.Collections; using System.Collections.Generic; using System.Xml.Serialization; using UnityEngine; public class CameraManager : MonoBehaviour { public static CameraManager _instance { get; private set; } private GameObject m_Brain; private Camera m_Camera; private GameObject m_ActiveCamera; private List m_CameraObjects = new List(); private int m_SameCameraTypeCount; [Header("Layer Masks")] public LayerMask m_Everything; public LayerMask m_Agent; public LayerMask m_Bodies; public LayerMask m_Environment; public LayerMask m_Actuations; [Header("Text Objects")] public GameObject m_Rewards; [Header("Camera Settings")] [Range(2, 20)] public int m_CameraBlendMin; [Range(2, 20)] public int m_CameraBlendMax; [Range(5, 180)] public int m_CameraSwapMin; [Range(5, 180)] public int m_CameraSwapMax; public bool m_CameraController; private int m_CameraIndex = 0; private void Awake() { if(_instance != null) Destroy(this); else _instance = this; } private void OnEnable() { CreateCameraList(); InitialCameraSetup(); SetCullingMask(); } private void Start() { if(!m_CameraController) StartCoroutine(CameraSwitch()); } private void Update(){ if (m_CameraController) CameraControllerInput(); } private void CameraControllerInput(){ var count = 0; if(Input.GetKeyDown(KeyCode.LeftArrow)){ if (m_CameraIndex != 0) m_CameraIndex--; } if(Input.GetKeyDown(KeyCode.RightArrow)){ if (m_CameraIndex != 1) m_CameraIndex++; } for(int i = 0 + (m_CameraIndex * 10); i < m_CameraObjects.Count; i++){ if(Input.GetKeyDown(KeyCode.Alpha0 + ( i - ( m_CameraIndex * 10 ) ))){ foreach(GameObject obj in m_CameraObjects){ if(count == i){ Debug.Log($"Swapping to:{obj.name}"); SetCamera(obj); break; } count++; } } } } IEnumerator CameraSwitch() { SetNewCamera(); yield return new WaitForSecondsRealtime(Random.Range(m_CameraSwapMin, m_CameraSwapMax)); StartCoroutine(CameraSwitch()); } private void SetCullingMask() { m_Camera = m_Brain.GetComponent(); string currentTag = m_ActiveCamera.tag; switch (currentTag) { case "vc_Agent": m_Camera.cullingMask = m_Agent; m_Rewards.SetActive(true); break; case "vc_Body": m_Camera.cullingMask = m_Bodies; m_Rewards.SetActive(false); break; case "vc_Environment": m_Camera.cullingMask = m_Environment; m_Rewards.SetActive(false); break; case "vc_Actuations": m_Camera.cullingMask = m_Actuations; m_Rewards.SetActive(true); break; } } private void SetNewCamera() { // Get all objects with 0 prio List deactiveCameras = new List(); bool switchCameraType = false; if (m_SameCameraTypeCount >= 3) switchCameraType = true; for(int i = 0; i < m_CameraObjects.Count; i++) { GameObject t = m_CameraObjects[i]; CinemachineVirtualCamera virtualCamera = t.GetComponent(); if (virtualCamera != null && virtualCamera.Priority == 0) { if (switchCameraType) { if(t.tag != m_ActiveCamera.tag) deactiveCameras.Add(i); } else { deactiveCameras.Add(i); } } } int randomIndex = deactiveCameras[Random.Range(0, deactiveCameras.Count - 1)]; GameObject selectedCamera = m_CameraObjects[randomIndex]; if (selectedCamera.tag == m_ActiveCamera.tag) { m_SameCameraTypeCount++; SetCamera(selectedCamera); } else { m_SameCameraTypeCount = 0; SetCamera(selectedCamera); } } private void SetCamera(GameObject camera) { SetCameraBlend(camera); // Set all camera to active, and set all priorities to 0, bar the first camera foreach (GameObject obj in m_CameraObjects) { CinemachineVirtualCamera vCam = obj.GetComponent(); vCam.Priority = 0; } camera.GetComponent().Priority = 1; m_ActiveCamera = camera; SetCullingMask(); } private void SetCameraBlend(GameObject pastCamera) { // Check activate camera tag, and apply the necessary blend-mode CinemachineBrain cmBrain = m_Brain.GetComponent(); float blendtime = (float)Random.Range(m_CameraBlendMin, m_CameraBlendMax); if (AreDifferentPairs(pastCamera.tag, m_ActiveCamera.tag, "vc_Body", "vc_Agent") || AreDifferentPairs(pastCamera.tag, m_ActiveCamera.tag, "vc_Environment", "vc_Agent") || AreDifferentPairs(pastCamera.tag, m_ActiveCamera.tag, "vc_Environment", "vc_Body") || AreDifferentPairs(pastCamera.tag, m_ActiveCamera.tag, "vc_Environment", "vc_Environment") || AreDifferentPairs(pastCamera.tag, m_ActiveCamera.tag, "vc_Body", "vc_Body") || AreDifferentPairs(pastCamera.tag, m_ActiveCamera.tag, "vc_Actuations", "vc_Body") || AreDifferentPairs(pastCamera.tag, m_ActiveCamera.tag, "vc_Actuations", "vc_Environment") || AreDifferentPairs(pastCamera.tag, m_ActiveCamera.tag, "vc_Actuations", "vc_Agent") || AreDifferentPairs(pastCamera.tag, m_ActiveCamera.tag, "vc_Actuations", "vc_Actuations")) blendtime = 0; cmBrain.m_DefaultBlend.m_Time = blendtime; } private bool AreDifferentPairs(string a, string b, string pair1, string pair2) { return (a == pair1 && b == pair2) || (a == pair2 && b == pair1); } private void InitialCameraSetup() { // Set all camera to active, and set all priorities to 0, bar the first camera foreach(GameObject obj in m_CameraObjects) { CinemachineVirtualCamera vCam = obj.GetComponent(); vCam.Priority = 0; } m_CameraObjects[0].GetComponent().Priority = 1; m_ActiveCamera = m_CameraObjects[0]; } private void CreateCameraList() { GameObject parentObject = GameObject.Find("CM List"); if(parentObject != null) { AddActiveChildrenRecursively(parentObject.transform); } else { Debug.LogError("CM List not found."); } try { m_Brain = GameObject.Find("CM Brain"); } catch { Debug.LogError("CM Brain could not be found."); } Debug.Log($"Camera Count: {m_CameraObjects.Count}"); } void AddActiveChildrenRecursively(Transform parentTransform) { foreach (Transform child in parentTransform) { if (child.gameObject.activeSelf && child.GetComponent() != null) { m_CameraObjects.Add(child.gameObject); } // Recursively call the function for each child AddActiveChildrenRecursively(child); } } }