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);
}
}
}