123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- using UnityEngine;
- using UnityEngine.SceneManagement;
- //-----------------------------------------------------------------------------
- // Copyright 2012-2022 RenderHeads Ltd. All rights reserved.
- //-----------------------------------------------------------------------------
- namespace RenderHeads.Media.AVProMovieCapture
- {
- /// <summary>
- /// Selects the camera to use for captures based on various factors
- /// TODO: add support for persisting across scene changes
- /// </summary>
- [AddComponentMenu("AVPro Movie Capture/Utils/Camera Selector", 300)]
- public class CameraSelector : MonoBehaviour
- {
- public enum SelectByMode
- {
- HighestDepthCamera,
- MainCameraTag,
- EditorSceneView,
- Tag,
- Name,
- Manual,
- }
- public enum ScanFrequencyMode
- {
- Manual,
- SceneLoad,
- Frame,
- }
- [SerializeField] SelectByMode _selectBy = SelectByMode.HighestDepthCamera;
- [SerializeField] ScanFrequencyMode _scanFrequency = ScanFrequencyMode.SceneLoad;
- [SerializeField] bool _scanHiddenCameras = false;
- [SerializeField] string _tag = "MainCamera";
- [SerializeField] string _name = "Main Camera";
- [SerializeField] Camera _camera = null;
- #if UNITY_EDITOR
- private const string SceneCameraName = "SceneCamera";
- #endif
- private Camera[] _cameraCache = new Camera[0];
- private int _cameraCount;
- private int _cameraCacheFrame = -1;
- private bool _selectionDirty = false;
- #if UNITY_EDITOR
- public int CameraCacheCount
- {
- get { return _cameraCount; }
- }
- public Camera[] CameraCache
- {
- get { return _cameraCache; }
- }
- #endif
- public Camera Camera
- {
- get { return _camera; }
- set { _camera = value; _selectBy = SelectByMode.Manual; }
- }
- public SelectByMode SelectBy
- {
- get { return _selectBy; }
- set { _selectBy = value; _selectionDirty = true; }
- }
- public ScanFrequencyMode ScanFrequency
- {
- get { return _scanFrequency; }
- set { _scanFrequency = value; ResetSceneLoading(); }
- }
- public bool ScanHiddenCameras
- {
- get { return _scanHiddenCameras; }
- set { _scanHiddenCameras = value; _selectionDirty = true; }
- }
- public string SelectTag
- {
- get { return _tag; }
- set { _tag = value; _selectionDirty = true; }
- }
- public string SelectName
- {
- get { return _name; }
- set { _name = value; _selectionDirty = true; }
- }
- void Awake()
- {
- ResetSceneLoading();
- }
- void Start()
- {
- ScanForCameraChange();
- }
- void OnValidate()
- {
- ResetSceneLoading();
- }
- void Update()
- {
- if (_selectionDirty || _scanFrequency == ScanFrequencyMode.Frame)
- {
- ScanForCameraChange();
- }
- }
- void OnDestroy()
- {
- SceneManager.sceneLoaded -= OnSceneLoaded;
- }
- void ResetSceneLoading()
- {
- SceneManager.sceneLoaded -= OnSceneLoaded;
- if (_scanFrequency == ScanFrequencyMode.SceneLoad)
- {
- SceneManager.sceneLoaded += OnSceneLoaded;
- }
- }
-
- void OnSceneLoaded(Scene scene, LoadSceneMode mode)
- {
- if (_scanFrequency == ScanFrequencyMode.SceneLoad)
- {
- ScanForCameraChange();
- }
- }
- public bool ScanForCameraChange()
- {
- bool result = false;
- Camera camera = FindCamera();
- if (_camera != camera)
- {
- _camera = camera;
- if (_camera != null)
- {
- //Debug.Log("Camera " + _camera.name);
- }
- result = true;
- }
- _selectionDirty = false;
- return result;
- }
- Camera FindCamera()
- {
- Camera result = null;
- switch (_selectBy)
- {
- case SelectByMode.HighestDepthCamera:
- UpdateCameraCache();
- result = FindCameraByHighestDepth(_cameraCount, _cameraCache);
- break;
- case SelectByMode.MainCameraTag:
- result = Camera.main;
- break;
- case SelectByMode.EditorSceneView:
- #if UNITY_EDITOR
- UpdateCameraCache(true);
- result = FindCameraByName(_cameraCount, _cameraCache, SceneCameraName);
- #else
- Debug.LogWarning("[AVProMovieCapture] Scene View can only be captured in the Unity editor. Select a different camera.");
- #endif
- break;
- case SelectByMode.Tag:
- UpdateCameraCache();
- result = FindCameraByTag(_cameraCount, _cameraCache, _tag);
- break;
- case SelectByMode.Name:
- UpdateCameraCache();
- result = FindCameraByName(_cameraCount, _cameraCache, _name);
- break;
- case SelectByMode.Manual:
- result = _camera;
- break;
- }
- return result;
- }
- public void UpdateCameraCache(bool forceScanHiddenCameras = false)
- {
- // Prevent multiple scans per frame
- if (Time.frameCount == _cameraCacheFrame) return;
- if (!_scanHiddenCameras && !forceScanHiddenCameras)
- {
- // FAST - list active cameras
- if (_cameraCache.Length < Camera.allCamerasCount)
- {
- _cameraCache = new Camera[Camera.allCamerasCount];
-
- }
- _cameraCount = Camera.GetAllCameras(_cameraCache);
- }
- else
- {
- // SLOW - list all cameras
- _cameraCache = Resources.FindObjectsOfTypeAll<Camera>();
- _cameraCount = _cameraCache.Length;
- }
- _cameraCacheFrame = Time.frameCount;
- }
- static Camera FindCameraByHighestDepth(int cameraCount, Camera[] cameras)
- {
- Camera result = null;
- float maxDepth = float.MinValue;
- for (int i = 0; i < cameraCount; i++)
- {
- Camera c = cameras[i];
- if (result == null || c.depth > maxDepth)
- {
- result = c;
- maxDepth = c.depth;
- }
- }
- return result;
- }
- static Camera FindCameraByTag(int cameraCount, Camera[] cameras, string tag)
- {
- Camera result = null;
- for (int i = 0; i < cameraCount; i++)
- {
- Camera c = cameras[i];
- if (c.CompareTag(tag))
- {
- result = c;
- break;
- }
- }
- return result;
- }
- static Camera FindCameraByName(int cameraCount, Camera[] cameras, string name)
- {
- Camera result = null;
- for (int i = 0; i < cameraCount; i++)
- {
- Camera c = cameras[i];
- if (c.name == name)
- {
- result = c;
- break;
- }
- }
- return result;
- }
- }
- }
|