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.

313 lines
9.1 KiB

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<GameObject> m_CameraObjects = new List<GameObject>();
private List<CameraSettings> m_CameraSettings = new List<CameraSettings>();
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;
[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}, {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<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 priority
List<int> deactiveCameras = new List<int>();
// 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<CinemachineVirtualCamera>();
if (virtualCamera != null && virtualCamera.Priority == 0)
deactiveCameras.Add(i);
}
List<int> 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<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}");
CreateCameraSettingsList();
}
private void CreateCameraSettingsList(){
VirtualCameraSettings camSettings = null;
foreach(GameObject cam in m_CameraObjects){
camSettings = null;
try{
camSettings = cam.GetComponent<VirtualCameraSettings>();
} 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<int> 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<CinemachineVirtualCamera>() != null)
{
m_CameraObjects.Add(child.gameObject);
}
// Recursively call the function for each child
AddActiveChildrenRecursively(child);
}
}
private List<int> ShuffleList(List<int> 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;
}
}