implementation of drecon in unity 2022 lts forked from: https://github.com/joanllobera/marathon-envs
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

267 lines
7.8 KiB

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<GameObject> m_CameraObjects = new List<GameObject>();
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<Camera>();
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<int> deactiveCameras = new List<int>();
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<CinemachineVirtualCamera>();
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<CinemachineVirtualCamera>();
vCam.Priority = 0;
}
camera.GetComponent<CinemachineVirtualCamera>().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<CinemachineBrain>();
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<CinemachineVirtualCamera>();
vCam.Priority = 0;
}
m_CameraObjects[0].GetComponent<CinemachineVirtualCamera>().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 <GameObject> not found.");
}
try
{
m_Brain = GameObject.Find("CM Brain");
}
catch
{
Debug.LogError("CM Brain <GameObject> 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<CinemachineVirtualCamera>() != null)
{
m_CameraObjects.Add(child.gameObject);
}
// Recursively call the function for each child
AddActiveChildrenRecursively(child);
}
}
}