UIPainter.cs 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. using System;
  2. using UnityEngine;
  3. namespace FairyGUI
  4. {
  5. /// <summary>
  6. ///
  7. /// </summary>
  8. [ExecuteInEditMode]
  9. [AddComponentMenu("FairyGUI/UI Painter")]
  10. [RequireComponent(typeof(MeshCollider), typeof(MeshRenderer))]
  11. public class UIPainter : MonoBehaviour, EMRenderTarget
  12. {
  13. /// <summary>
  14. ///
  15. /// </summary>
  16. public Container container { get; private set; }
  17. /// <summary>
  18. ///
  19. /// </summary>
  20. public string packageName;
  21. /// <summary>
  22. ///
  23. /// </summary>
  24. public string componentName;
  25. /// <summary>
  26. ///
  27. /// </summary>
  28. public int sortingOrder;
  29. [SerializeField]
  30. string packagePath;
  31. [SerializeField]
  32. Camera renderCamera = null;
  33. [SerializeField]
  34. bool fairyBatching = false;
  35. [SerializeField]
  36. bool touchDisabled = false;
  37. GComponent _ui;
  38. [NonSerialized]
  39. bool _created;
  40. [NonSerialized]
  41. bool _captured;
  42. [NonSerialized]
  43. Renderer _renderer;
  44. [NonSerialized]
  45. RenderTexture _texture;
  46. Action _captureDelegate;
  47. void OnEnable()
  48. {
  49. if (Application.isPlaying)
  50. {
  51. if (this.container == null)
  52. {
  53. CreateContainer();
  54. if (!string.IsNullOrEmpty(packagePath) && UIPackage.GetByName(packageName) == null)
  55. UIPackage.AddPackage(packagePath);
  56. }
  57. }
  58. else
  59. {
  60. EMRenderSupport.Add(this);
  61. }
  62. }
  63. void OnDisable()
  64. {
  65. if (!Application.isPlaying)
  66. EMRenderSupport.Remove(this);
  67. }
  68. void OnGUI()
  69. {
  70. if (!Application.isPlaying)
  71. EM_BeforeUpdate();
  72. }
  73. void Start()
  74. {
  75. useGUILayout = false;
  76. if (!_created && Application.isPlaying)
  77. CreateUI();
  78. }
  79. void OnDestroy()
  80. {
  81. if (Application.isPlaying)
  82. {
  83. if (_ui != null)
  84. {
  85. _ui.Dispose();
  86. _ui = null;
  87. }
  88. container.Dispose();
  89. container = null;
  90. }
  91. else
  92. {
  93. EMRenderSupport.Remove(this);
  94. }
  95. DestroyTexture();
  96. }
  97. void CreateContainer()
  98. {
  99. this.container = new Container("UIPainter");
  100. this.container.renderMode = RenderMode.WorldSpace;
  101. this.container.renderCamera = renderCamera;
  102. this.container.touchable = !touchDisabled;
  103. this.container.fairyBatching = fairyBatching;
  104. this.container._panelOrder = sortingOrder;
  105. this.container.hitArea = new MeshColliderHitTest(this.gameObject.GetComponent<MeshCollider>());
  106. SetSortingOrder(this.sortingOrder, true);
  107. this.container.layer = CaptureCamera.hiddenLayer;
  108. }
  109. /// <summary>
  110. /// Change the sorting order of the panel in runtime.
  111. /// </summary>
  112. /// <param name="value">sorting order value</param>
  113. /// <param name="apply">false if you dont want the default sorting behavior.</param>
  114. public void SetSortingOrder(int value, bool apply)
  115. {
  116. this.sortingOrder = value;
  117. container._panelOrder = value;
  118. if (apply)
  119. Stage.inst.ApplyPanelOrder(container);
  120. }
  121. /// <summary>
  122. ///
  123. /// </summary>
  124. public GComponent ui
  125. {
  126. get
  127. {
  128. if (!_created && Application.isPlaying)
  129. CreateUI();
  130. return _ui;
  131. }
  132. }
  133. /// <summary>
  134. ///
  135. /// </summary>
  136. public void CreateUI()
  137. {
  138. if (_ui != null)
  139. {
  140. _ui.Dispose();
  141. _ui = null;
  142. DestroyTexture();
  143. }
  144. _created = true;
  145. if (string.IsNullOrEmpty(packageName) || string.IsNullOrEmpty(componentName))
  146. return;
  147. _ui = (GComponent)UIPackage.CreateObject(packageName, componentName);
  148. if (_ui != null)
  149. {
  150. this.container.AddChild(_ui.displayObject);
  151. this.container.size = _ui.size;
  152. _texture = CaptureCamera.CreateRenderTexture(Mathf.RoundToInt(_ui.width), Mathf.RoundToInt(_ui.height), UIConfig.depthSupportForPaintingMode);
  153. _renderer = this.GetComponent<Renderer>();
  154. if (_renderer != null)
  155. {
  156. _renderer.sharedMaterial.mainTexture = _texture;
  157. _captureDelegate = Capture;
  158. if (_renderer.sharedMaterial.renderQueue == 3000) //Set in transpare queue only
  159. {
  160. this.container.onUpdate += () =>
  161. {
  162. UpdateContext.OnEnd += _captureDelegate;
  163. };
  164. }
  165. }
  166. }
  167. else
  168. Debug.LogError("Create " + componentName + "@" + packageName + " failed!");
  169. }
  170. void Capture()
  171. {
  172. CaptureCamera.Capture(this.container, _texture, this.container.size.y, Vector2.zero);
  173. if (_renderer != null)
  174. _renderer.sortingOrder = container.renderingOrder;
  175. }
  176. void DestroyTexture()
  177. {
  178. if (_texture != null)
  179. {
  180. if (Application.isPlaying)
  181. RenderTexture.Destroy(_texture);
  182. else
  183. RenderTexture.DestroyImmediate(_texture);
  184. _texture = null;
  185. if (_renderer != null)
  186. _renderer.sharedMaterial.mainTexture = null;
  187. }
  188. }
  189. #region edit mode functions
  190. void CaptureInEditMode()
  191. {
  192. if (!EMRenderSupport.packageListReady || UIPackage.GetByName(packageName) == null)
  193. return;
  194. _captured = true;
  195. DisplayObject.hideFlags = HideFlags.DontSaveInEditor;
  196. GComponent view = (GComponent)UIPackage.CreateObject(packageName, componentName);
  197. if (view != null)
  198. {
  199. DestroyTexture();
  200. _texture = CaptureCamera.CreateRenderTexture(Mathf.RoundToInt(view.width), Mathf.RoundToInt(view.height), false);
  201. Container root = (Container)view.displayObject;
  202. root.layer = CaptureCamera.layer;
  203. root.gameObject.hideFlags = HideFlags.None;
  204. root.gameObject.SetActive(true);
  205. GameObject cameraObject = new GameObject("Temp Capture Camera");
  206. Camera camera = cameraObject.AddComponent<Camera>();
  207. camera.depth = 0;
  208. camera.cullingMask = 1 << CaptureCamera.layer;
  209. camera.clearFlags = CameraClearFlags.Depth;
  210. camera.orthographic = true;
  211. camera.nearClipPlane = -30;
  212. camera.farClipPlane = 30;
  213. camera.enabled = false;
  214. camera.targetTexture = _texture;
  215. float halfHeight = (float)_texture.height / 2;
  216. camera.orthographicSize = halfHeight;
  217. cameraObject.transform.localPosition = root.cachedTransform.TransformPoint(halfHeight * camera.aspect, -halfHeight, 0);
  218. UpdateContext context = new UpdateContext();
  219. //run two times
  220. context.Begin();
  221. view.displayObject.Update(context);
  222. context.End();
  223. context.Begin();
  224. view.displayObject.Update(context);
  225. context.End();
  226. RenderTexture old = RenderTexture.active;
  227. RenderTexture.active = _texture;
  228. GL.Clear(true, true, Color.clear);
  229. camera.Render();
  230. RenderTexture.active = old;
  231. camera.targetTexture = null;
  232. view.Dispose();
  233. GameObject.DestroyImmediate(cameraObject);
  234. if (_renderer != null)
  235. _renderer.sharedMaterial.mainTexture = _texture;
  236. }
  237. }
  238. public void ApplyModifiedProperties(bool sortingOrderChanged)
  239. {
  240. if (sortingOrderChanged)
  241. {
  242. if (Application.isPlaying)
  243. SetSortingOrder(sortingOrder, true);
  244. else
  245. EMRenderSupport.orderChanged = true;
  246. }
  247. }
  248. public void OnUpdateSource(object[] data)
  249. {
  250. if (Application.isPlaying)
  251. return;
  252. this.packageName = (string)data[0];
  253. this.packagePath = (string)data[1];
  254. this.componentName = (string)data[2];
  255. if ((bool)data[3])
  256. _captured = false;
  257. }
  258. public int EM_sortingOrder
  259. {
  260. get { return sortingOrder; }
  261. }
  262. public void EM_BeforeUpdate()
  263. {
  264. if (_renderer == null)
  265. _renderer = this.GetComponent<Renderer>();
  266. if (_renderer != null && _renderer.sharedMaterial.mainTexture != _texture)
  267. _renderer.sharedMaterial.mainTexture = _texture;
  268. if (packageName != null && componentName != null && !_captured)
  269. CaptureInEditMode();
  270. }
  271. public void EM_Update(UpdateContext context)
  272. {
  273. if (_renderer != null)
  274. _renderer.sortingOrder = context.renderingOrder++;
  275. }
  276. public void EM_Reload()
  277. {
  278. _captured = false;
  279. }
  280. #endregion
  281. }
  282. }