206 lines
6.6 KiB
C#
206 lines
6.6 KiB
C#
|
using UnityEngine;
|
|||
|
|
|||
|
namespace FairyGUI
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
public class CaptureCamera : MonoBehaviour
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
[System.NonSerialized]
|
|||
|
public Transform cachedTransform;
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
[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";
|
|||
|
|
|||
|
#if UNITY_2019_3_OR_NEWER
|
|||
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
|||
|
static void Init()
|
|||
|
{
|
|||
|
_main = null;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
void OnEnable()
|
|||
|
{
|
|||
|
cachedCamera = this.GetComponent<Camera>();
|
|||
|
cachedTransform = this.gameObject.transform;
|
|||
|
|
|||
|
if (this.gameObject.name == Name)
|
|||
|
_main = this;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
public static void CheckMain()
|
|||
|
{
|
|||
|
if (_main != null && _main.cachedCamera != null)
|
|||
|
return;
|
|||
|
|
|||
|
GameObject go = GameObject.Find(Name);
|
|||
|
if (go != null)
|
|||
|
{
|
|||
|
_main = go.GetComponent<CaptureCamera>();
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
GameObject cameraObject = new GameObject(Name);
|
|||
|
Camera camera = cameraObject.AddComponent<Camera>();
|
|||
|
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;
|
|||
|
camera.stereoTargetEye = StereoTargetEyeMask.None;
|
|||
|
camera.allowHDR = false;
|
|||
|
camera.allowMSAA = false;
|
|||
|
cameraObject.AddComponent<CaptureCamera>();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
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;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
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;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
/// <param name="width"></param>
|
|||
|
/// <param name="height"></param>
|
|||
|
/// <param name="stencilSupport"></param>
|
|||
|
/// <returns></returns>
|
|||
|
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;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
/// <param name="target"></param>
|
|||
|
/// <param name="texture"></param>
|
|||
|
/// <param name="contentHeight"></param>
|
|||
|
/// <param name="offset"></param>
|
|||
|
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._SetLayerDirect(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._SetLayerDirect(oldLayer);
|
|||
|
|
|||
|
if (target is Container)
|
|||
|
((Container)target).SetChildrenLayer(oldLayer);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|