CaptureCamera.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. using UnityEngine;
  2. namespace FairyGUI
  3. {
  4. /// <summary>
  5. ///
  6. /// </summary>
  7. public class CaptureCamera : MonoBehaviour
  8. {
  9. /// <summary>
  10. ///
  11. /// </summary>
  12. [System.NonSerialized]
  13. public Transform cachedTransform;
  14. /// <summary>
  15. ///
  16. /// </summary>
  17. [System.NonSerialized]
  18. public Camera cachedCamera;
  19. [System.NonSerialized]
  20. static CaptureCamera _main;
  21. [System.NonSerialized]
  22. static int _layer = -1;
  23. static int _hiddenLayer = -1;
  24. public const string Name = "Capture Camera";
  25. public const string LayerName = "VUI";
  26. public const string HiddenLayerName = "Hidden VUI";
  27. void OnEnable()
  28. {
  29. cachedCamera = this.GetComponent<Camera>();
  30. cachedTransform = this.gameObject.transform;
  31. if (this.gameObject.name == Name)
  32. _main = this;
  33. }
  34. /// <summary>
  35. ///
  36. /// </summary>
  37. public static void CheckMain()
  38. {
  39. if (_main != null && _main.cachedCamera != null)
  40. return;
  41. GameObject go = GameObject.Find(Name);
  42. if (go != null)
  43. {
  44. _main = go.GetComponent<CaptureCamera>();
  45. return;
  46. }
  47. GameObject cameraObject = new GameObject(Name);
  48. Camera camera = cameraObject.AddComponent<Camera>();
  49. camera.depth = 0;
  50. camera.cullingMask = 1 << layer;
  51. camera.clearFlags = CameraClearFlags.SolidColor;
  52. camera.backgroundColor = Color.clear;
  53. camera.orthographic = true;
  54. camera.orthographicSize = 5;
  55. camera.nearClipPlane = -30;
  56. camera.farClipPlane = 30;
  57. camera.enabled = false;
  58. #if UNITY_5_4_OR_NEWER
  59. camera.stereoTargetEye = StereoTargetEyeMask.None;
  60. #endif
  61. #if UNITY_5_6_OR_NEWER
  62. camera.allowHDR = false;
  63. camera.allowMSAA = false;
  64. #endif
  65. cameraObject.AddComponent<CaptureCamera>();
  66. }
  67. /// <summary>
  68. ///
  69. /// </summary>
  70. public static int layer
  71. {
  72. get
  73. {
  74. if (_layer == -1)
  75. {
  76. _layer = LayerMask.NameToLayer(LayerName);
  77. if (_layer == -1)
  78. {
  79. _layer = 30;
  80. Debug.LogWarning("Please define two layers named '" + CaptureCamera.LayerName + "' and '" + CaptureCamera.HiddenLayerName + "'");
  81. }
  82. }
  83. return _layer;
  84. }
  85. }
  86. /// <summary>
  87. ///
  88. /// </summary>
  89. public static int hiddenLayer
  90. {
  91. get
  92. {
  93. if (_hiddenLayer == -1)
  94. {
  95. _hiddenLayer = LayerMask.NameToLayer(HiddenLayerName);
  96. if (_hiddenLayer == -1)
  97. {
  98. Debug.LogWarning("Please define two layers named '" + CaptureCamera.LayerName + "' and '" + CaptureCamera.HiddenLayerName + "'");
  99. _hiddenLayer = 31;
  100. }
  101. }
  102. return _hiddenLayer;
  103. }
  104. }
  105. /// <summary>
  106. ///
  107. /// </summary>
  108. /// <param name="width"></param>
  109. /// <param name="height"></param>
  110. /// <param name="stencilSupport"></param>
  111. /// <returns></returns>
  112. public static RenderTexture CreateRenderTexture(int width, int height, bool stencilSupport)
  113. {
  114. RenderTexture texture = new RenderTexture(width, height, stencilSupport ? 24 : 0, RenderTextureFormat.ARGB32);
  115. texture.antiAliasing = 1;
  116. texture.filterMode = FilterMode.Bilinear;
  117. texture.anisoLevel = 0;
  118. texture.useMipMap = false;
  119. texture.wrapMode = TextureWrapMode.Clamp;
  120. texture.hideFlags = DisplayObject.hideFlags;
  121. return texture;
  122. }
  123. /// <summary>
  124. ///
  125. /// </summary>
  126. /// <param name="target"></param>
  127. /// <param name="texture"></param>
  128. /// <param name="contentHeight"></param>
  129. /// <param name="offset"></param>
  130. public static void Capture(DisplayObject target, RenderTexture texture, float contentHeight, Vector2 offset)
  131. {
  132. CheckMain();
  133. Matrix4x4 matrix = target.cachedTransform.localToWorldMatrix;
  134. float scaleX = new Vector4(matrix.m00, matrix.m10, matrix.m20, matrix.m30).magnitude;
  135. float scaleY = new Vector4(matrix.m01, matrix.m11, matrix.m21, matrix.m31).magnitude;
  136. Vector3 forward;
  137. forward.x = matrix.m02;
  138. forward.y = matrix.m12;
  139. forward.z = matrix.m22;
  140. Vector3 upwards;
  141. upwards.x = matrix.m01;
  142. upwards.y = matrix.m11;
  143. upwards.z = matrix.m21;
  144. float halfHeight = contentHeight * 0.5f;
  145. Camera camera = _main.cachedCamera;
  146. camera.targetTexture = texture;
  147. float aspect = (float)texture.width / texture.height;
  148. camera.aspect = aspect * scaleX / scaleY;
  149. camera.orthographicSize = halfHeight * scaleY;
  150. _main.cachedTransform.localPosition = target.cachedTransform.TransformPoint(halfHeight * aspect - offset.x, -halfHeight + offset.y, 0);
  151. if (forward != Vector3.zero)
  152. _main.cachedTransform.localRotation = Quaternion.LookRotation(forward, upwards);
  153. int oldLayer = 0;
  154. if (target.graphics != null)
  155. {
  156. oldLayer = target.graphics.gameObject.layer;
  157. target.graphics.gameObject.layer = CaptureCamera.layer;
  158. }
  159. if (target is Container)
  160. {
  161. oldLayer = ((Container)target).numChildren > 0 ? ((Container)target).GetChildAt(0).layer : CaptureCamera.hiddenLayer;
  162. ((Container)target).SetChildrenLayer(CaptureCamera.layer);
  163. }
  164. RenderTexture old = RenderTexture.active;
  165. RenderTexture.active = texture;
  166. GL.Clear(true, true, Color.clear);
  167. camera.Render();
  168. RenderTexture.active = old;
  169. if (target.graphics != null)
  170. target.graphics.gameObject.layer = oldLayer;
  171. if (target is Container)
  172. ((Container)target).SetChildrenLayer(oldLayer);
  173. }
  174. }
  175. }