using Cinemachine; using FMODUnity; 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 List m_CameraSettings = new List(); private float m_TotalWeight = 0; 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; public LayerMask m_Compare; [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; [Header("Shader")] public Material m_HumanoidMaterial; public Color m_BackgroundColor; 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}, {m_CameraSettings[i].cameraWeight}"); 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; case "vc_Compare": m_Camera.cullingMask = m_Compare; m_Rewards.SetActive(true); break; } } private void SetNewCamera() { // Get all objects with 0 priority List deactiveCameras = new List(); // Count through camera objects, check if 0 priority (off), we add to // list of deactivated cameras. for(int i = 0; i < m_CameraObjects.Count; i++) { GameObject t = m_CameraObjects[i]; CinemachineVirtualCamera virtualCamera = t.GetComponent(); if (virtualCamera != null && virtualCamera.Priority == 0) deactiveCameras.Add(i); } List shuffledList = ShuffleList(deactiveCameras); float totalWeight = CalculateNewTotalWeight(shuffledList); float randomIndex = Random.Range(0f, totalWeight); Debug.Log($"Random Number: {randomIndex}"); GameObject selectedCamera = null; int selectedCameraIndex = 0; for (int i = 0; i < shuffledList.Count; i++){ randomIndex -= m_CameraSettings[shuffledList[i]].cameraWeight; Debug.Log($"Adj Index: {randomIndex}, Weight: {totalWeight}, {m_CameraSettings[shuffledList[i]].cameraWeight}, Name: {m_CameraObjects[shuffledList[i]].name}"); if(randomIndex <= 0){ // Activate Selected Camera selectedCamera = m_CameraObjects[shuffledList[i]]; selectedCameraIndex = shuffledList[i]; break; } } Debug.Log($"Selected Camera: {selectedCamera.name}, {m_CameraSettings[selectedCameraIndex].cameraWeight}"); 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") || AreDifferentPairs(pastCamera.tag, m_ActiveCamera.tag, "vc_Actuations", "vc_Compare") || AreDifferentPairs(pastCamera.tag, m_ActiveCamera.tag, "vc_Compare", "vc_Compare") || AreDifferentPairs(pastCamera.tag, m_ActiveCamera.tag, "vc_Environment", "vc_Compare") || AreDifferentPairs(pastCamera.tag, m_ActiveCamera.tag, "vc_Body", "vc_Compare")) 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"); // Set dissapear color same as sky color m_Brain.GetComponent().backgroundColor = m_BackgroundColor; Debug.Log(m_BackgroundColor); m_HumanoidMaterial.SetColor("_DissapearColor", m_BackgroundColor); } catch { Debug.LogError("CM Brain could not be found."); } Debug.Log($"Camera Count: {m_CameraObjects.Count}"); CreateCameraSettingsList(); } private void CreateCameraSettingsList(){ VirtualCameraSettings camSettings = null; foreach(GameObject cam in m_CameraObjects){ camSettings = null; try{ camSettings = cam.GetComponent(); } catch { Debug.LogError("No Camera Settings found."); } if(camSettings != null){ m_CameraSettings.Add(camSettings.m_CameraSettings); m_TotalWeight += camSettings.m_CameraSettings.cameraWeight; } } Debug.Log($"Total Weight: {m_TotalWeight}"); } private float CalculateNewTotalWeight(List deactiveCameras){ float totalWeight = 0; foreach(int index in deactiveCameras){ totalWeight += m_CameraSettings[index].cameraWeight; } return totalWeight; } 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); } } private List ShuffleList(List list){ for (int i = list.Count - 1; i > 0; i--){ int j = Random.Range(0, i + 1); int temp = list[i]; list[i] = list[j]; list[j] = temp; } return list; } }