using UnityEngine; namespace FairyGUI { /// /// /// public class CaptureCamera : MonoBehaviour { /// /// /// [System.NonSerialized] public Transform cachedTransform; /// /// /// [System.NonSerialized] public Camera cachedCamera; [System.NonSerialized] static CaptureCamera _main; [System.NonSerialized] static int _layer = -1; static int _hiddenLayer = -1; public const string Name = "Capture Camera"; public const string LayerName = "VUI"; public const string HiddenLayerName = "Hidden VUI"; void OnEnable() { cachedCamera = this.GetComponent(); cachedTransform = this.gameObject.transform; if (this.gameObject.name == Name) _main = this; } /// /// /// public static void CheckMain() { if (_main != null && _main.cachedCamera != null) return; GameObject go = GameObject.Find(Name); if (go != null) { _main = go.GetComponent(); return; } GameObject cameraObject = new GameObject(Name); Camera camera = cameraObject.AddComponent(); camera.depth = 0; camera.cullingMask = 1 << layer; camera.clearFlags = CameraClearFlags.SolidColor; camera.backgroundColor = Color.clear; camera.orthographic = true; camera.orthographicSize = 5; camera.nearClipPlane = -30; camera.farClipPlane = 30; camera.enabled = false; #if UNITY_5_4_OR_NEWER camera.stereoTargetEye = StereoTargetEyeMask.None; #endif #if UNITY_5_6_OR_NEWER camera.allowHDR = false; camera.allowMSAA = false; #endif cameraObject.AddComponent(); } /// /// /// public static int layer { get { if (_layer == -1) { _layer = LayerMask.NameToLayer(LayerName); if (_layer == -1) { _layer = 30; Debug.LogWarning("Please define two layers named '" + CaptureCamera.LayerName + "' and '" + CaptureCamera.HiddenLayerName + "'"); } } return _layer; } } /// /// /// public static int hiddenLayer { get { if (_hiddenLayer == -1) { _hiddenLayer = LayerMask.NameToLayer(HiddenLayerName); if (_hiddenLayer == -1) { Debug.LogWarning("Please define two layers named '" + CaptureCamera.LayerName + "' and '" + CaptureCamera.HiddenLayerName + "'"); _hiddenLayer = 31; } } return _hiddenLayer; } } /// /// /// /// /// /// /// public static RenderTexture CreateRenderTexture(int width, int height, bool stencilSupport) { RenderTexture texture = new RenderTexture(width, height, stencilSupport ? 24 : 0, RenderTextureFormat.ARGB32); texture.antiAliasing = 1; texture.filterMode = FilterMode.Bilinear; texture.anisoLevel = 0; texture.useMipMap = false; texture.wrapMode = TextureWrapMode.Clamp; texture.hideFlags = DisplayObject.hideFlags; return texture; } /// /// /// /// /// /// /// public static void Capture(DisplayObject target, RenderTexture texture, float contentHeight, Vector2 offset) { CheckMain(); Matrix4x4 matrix = target.cachedTransform.localToWorldMatrix; float scaleX = new Vector4(matrix.m00, matrix.m10, matrix.m20, matrix.m30).magnitude; float scaleY = new Vector4(matrix.m01, matrix.m11, matrix.m21, matrix.m31).magnitude; Vector3 forward; forward.x = matrix.m02; forward.y = matrix.m12; forward.z = matrix.m22; Vector3 upwards; upwards.x = matrix.m01; upwards.y = matrix.m11; upwards.z = matrix.m21; float halfHeight = contentHeight * 0.5f; Camera camera = _main.cachedCamera; camera.targetTexture = texture; float aspect = (float)texture.width / texture.height; camera.aspect = aspect * scaleX / scaleY; camera.orthographicSize = halfHeight * scaleY; _main.cachedTransform.localPosition = target.cachedTransform.TransformPoint(halfHeight * aspect - offset.x, -halfHeight + offset.y, 0); if (forward != Vector3.zero) _main.cachedTransform.localRotation = Quaternion.LookRotation(forward, upwards); int oldLayer = 0; if (target.graphics != null) { oldLayer = target.graphics.gameObject.layer; target.graphics.gameObject.layer = CaptureCamera.layer; } if (target is Container) { oldLayer = ((Container)target).numChildren > 0 ? ((Container)target).GetChildAt(0).layer : CaptureCamera.hiddenLayer; ((Container)target).SetChildrenLayer(CaptureCamera.layer); } RenderTexture old = RenderTexture.active; RenderTexture.active = texture; GL.Clear(true, true, Color.clear); camera.Render(); RenderTexture.active = old; if (target.graphics != null) target.graphics.gameObject.layer = oldLayer; if (target is Container) ((Container)target).SetChildrenLayer(oldLayer); } } }