using System; using UnityEngine; namespace Coffee.UIExtensions { internal class BakingCamera : MonoBehaviour { static BakingCamera s_Instance; #if UNITY_2018_3_OR_NEWER && UNITY_EDITOR static BakingCamera s_InstanceForPrefab; private static BakingCamera InstanceForPrefab { get { // If current scene is prefab mode, create OverlayCamera for editor. var prefabStage = UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage(); if (prefabStage == null || !prefabStage.scene.isLoaded) return null; if (s_InstanceForPrefab) return s_InstanceForPrefab; s_InstanceForPrefab = Create(); s_InstanceForPrefab.name += " (For Prefab Stage)"; UnityEngine.SceneManagement.SceneManager.MoveGameObjectToScene(s_InstanceForPrefab.gameObject, prefabStage.scene); return s_InstanceForPrefab; } } #endif private static BakingCamera Instance { get { #if UNITY_2018_3_OR_NEWER && UNITY_EDITOR var inst = InstanceForPrefab; if (inst) return inst; #endif // Find instance in scene, or create new one. return s_Instance ? s_Instance : (s_Instance = FindObjectOfType() ?? Create()); } } private Camera _camera; private int _refCount; private static BakingCamera Create() { var gameObject = new GameObject(typeof(BakingCamera).Name); // This camera object is just for internal use gameObject.hideFlags = HideFlags.HideAndDontSave; gameObject.hideFlags = HideFlags.DontSave; var inst = gameObject.AddComponent(); inst._camera = gameObject.AddComponent(); inst._camera.orthographic = true; // Turn camera off because particle mesh baker will use only camera matrix gameObject.SetActive(false); return inst; } private void Awake() { if (this == s_Instance) DontDestroyOnLoad(gameObject); } public static void Register() { Instance._refCount++; } public static void Unregister() { if (s_Instance == null) return; Instance._refCount--; if (0 < Instance._refCount) return; if (Application.isPlaying) Destroy(Instance.gameObject); else DestroyImmediate(Instance.gameObject); s_Instance = null; } public static Camera GetCamera(Canvas canvas) { if (!canvas) return Camera.main; canvas = canvas.rootCanvas; // Adjust camera orthographic size to canvas size // for canvas-based coordinates of particles' size and speed. var size = ((RectTransform) canvas.transform).rect.size; Instance._camera.orthographicSize = Mathf.Max(size.x, size.y) * canvas.scaleFactor; var camera = canvas.worldCamera; var transform = Instance.transform; if (canvas.renderMode != RenderMode.ScreenSpaceOverlay && camera) { var cameraTr = camera.transform; transform.SetPositionAndRotation(cameraTr.position, cameraTr.rotation); } else { Instance._camera.orthographic = true; transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity); } return Instance._camera; } } }