123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- using System;
- using UnityEngine;
- namespace FairyGUI
- {
- /// <summary>
- ///
- /// </summary>
- [ExecuteInEditMode]
- [AddComponentMenu("FairyGUI/UI Painter")]
- [RequireComponent(typeof(MeshCollider), typeof(MeshRenderer))]
- public class UIPainter : MonoBehaviour, EMRenderTarget
- {
- /// <summary>
- ///
- /// </summary>
- public Container container { get; private set; }
- /// <summary>
- ///
- /// </summary>
- public string packageName;
- /// <summary>
- ///
- /// </summary>
- public string componentName;
- /// <summary>
- ///
- /// </summary>
- public int sortingOrder;
- [SerializeField]
- string packagePath;
- [SerializeField]
- Camera renderCamera = null;
- [SerializeField]
- bool fairyBatching = false;
- [SerializeField]
- bool touchDisabled = false;
- GComponent _ui;
- [NonSerialized]
- bool _created;
- [NonSerialized]
- bool _captured;
- [NonSerialized]
- Renderer _renderer;
- [NonSerialized]
- RenderTexture _texture;
- Action _captureDelegate;
- void OnEnable()
- {
- if (Application.isPlaying)
- {
- if (this.container == null)
- {
- CreateContainer();
- if (!string.IsNullOrEmpty(packagePath) && UIPackage.GetByName(packageName) == null)
- UIPackage.AddPackage(packagePath);
- }
- }
- else
- {
- EMRenderSupport.Add(this);
- }
- }
- void OnDisable()
- {
- if (!Application.isPlaying)
- EMRenderSupport.Remove(this);
- }
- void OnGUI()
- {
- if (!Application.isPlaying)
- EM_BeforeUpdate();
- }
- void Start()
- {
- useGUILayout = false;
- if (!_created && Application.isPlaying)
- CreateUI();
- }
- void OnDestroy()
- {
- if (Application.isPlaying)
- {
- if (_ui != null)
- {
- _ui.Dispose();
- _ui = null;
- }
- container.Dispose();
- container = null;
- }
- else
- {
- EMRenderSupport.Remove(this);
- }
- DestroyTexture();
- }
- void CreateContainer()
- {
- this.container = new Container("UIPainter");
- this.container.renderMode = RenderMode.WorldSpace;
- this.container.renderCamera = renderCamera;
- this.container.touchable = !touchDisabled;
- this.container.fairyBatching = fairyBatching;
- this.container._panelOrder = sortingOrder;
- this.container.hitArea = new MeshColliderHitTest(this.gameObject.GetComponent<MeshCollider>());
- SetSortingOrder(this.sortingOrder, true);
- this.container.layer = CaptureCamera.hiddenLayer;
- }
- /// <summary>
- /// Change the sorting order of the panel in runtime.
- /// </summary>
- /// <param name="value">sorting order value</param>
- /// <param name="apply">false if you dont want the default sorting behavior.</param>
- public void SetSortingOrder(int value, bool apply)
- {
- this.sortingOrder = value;
- container._panelOrder = value;
- if (apply)
- Stage.inst.ApplyPanelOrder(container);
- }
- /// <summary>
- ///
- /// </summary>
- public GComponent ui
- {
- get
- {
- if (!_created && Application.isPlaying)
- CreateUI();
- return _ui;
- }
- }
- /// <summary>
- ///
- /// </summary>
- public void CreateUI()
- {
- if (_ui != null)
- {
- _ui.Dispose();
- _ui = null;
- DestroyTexture();
- }
- _created = true;
- if (string.IsNullOrEmpty(packageName) || string.IsNullOrEmpty(componentName))
- return;
- _ui = (GComponent)UIPackage.CreateObject(packageName, componentName);
- if (_ui != null)
- {
- this.container.AddChild(_ui.displayObject);
- this.container.size = _ui.size;
- _texture = CaptureCamera.CreateRenderTexture(Mathf.RoundToInt(_ui.width), Mathf.RoundToInt(_ui.height), UIConfig.depthSupportForPaintingMode);
- _renderer = this.GetComponent<Renderer>();
- if (_renderer != null)
- {
- _renderer.sharedMaterial.mainTexture = _texture;
- _captureDelegate = Capture;
- if (_renderer.sharedMaterial.renderQueue == 3000) //Set in transpare queue only
- {
- this.container.onUpdate += () =>
- {
- UpdateContext.OnEnd += _captureDelegate;
- };
- }
- }
- }
- else
- Debug.LogError("Create " + componentName + "@" + packageName + " failed!");
- }
- void Capture()
- {
- CaptureCamera.Capture(this.container, _texture, this.container.size.y, Vector2.zero);
- if (_renderer != null)
- _renderer.sortingOrder = container.renderingOrder;
- }
- void DestroyTexture()
- {
- if (_texture != null)
- {
- if (Application.isPlaying)
- RenderTexture.Destroy(_texture);
- else
- RenderTexture.DestroyImmediate(_texture);
- _texture = null;
- if (_renderer != null)
- _renderer.sharedMaterial.mainTexture = null;
- }
- }
- #region edit mode functions
- void CaptureInEditMode()
- {
- if (!EMRenderSupport.packageListReady || UIPackage.GetByName(packageName) == null)
- return;
- _captured = true;
- DisplayObject.hideFlags = HideFlags.DontSaveInEditor;
- GComponent view = (GComponent)UIPackage.CreateObject(packageName, componentName);
- if (view != null)
- {
- DestroyTexture();
- _texture = CaptureCamera.CreateRenderTexture(Mathf.RoundToInt(view.width), Mathf.RoundToInt(view.height), false);
- Container root = (Container)view.displayObject;
- root.layer = CaptureCamera.layer;
- root.gameObject.hideFlags = HideFlags.None;
- root.gameObject.SetActive(true);
- GameObject cameraObject = new GameObject("Temp Capture Camera");
- Camera camera = cameraObject.AddComponent<Camera>();
- camera.depth = 0;
- camera.cullingMask = 1 << CaptureCamera.layer;
- camera.clearFlags = CameraClearFlags.Depth;
- camera.orthographic = true;
- camera.nearClipPlane = -30;
- camera.farClipPlane = 30;
- camera.enabled = false;
- camera.targetTexture = _texture;
- float halfHeight = (float)_texture.height / 2;
- camera.orthographicSize = halfHeight;
- cameraObject.transform.localPosition = root.cachedTransform.TransformPoint(halfHeight * camera.aspect, -halfHeight, 0);
- UpdateContext context = new UpdateContext();
- //run two times
- context.Begin();
- view.displayObject.Update(context);
- context.End();
- context.Begin();
- view.displayObject.Update(context);
- context.End();
- RenderTexture old = RenderTexture.active;
- RenderTexture.active = _texture;
- GL.Clear(true, true, Color.clear);
- camera.Render();
- RenderTexture.active = old;
- camera.targetTexture = null;
- view.Dispose();
- GameObject.DestroyImmediate(cameraObject);
- if (_renderer != null)
- _renderer.sharedMaterial.mainTexture = _texture;
- }
- }
- public void ApplyModifiedProperties(bool sortingOrderChanged)
- {
- if (sortingOrderChanged)
- {
- if (Application.isPlaying)
- SetSortingOrder(sortingOrder, true);
- else
- EMRenderSupport.orderChanged = true;
- }
- }
- public void OnUpdateSource(object[] data)
- {
- if (Application.isPlaying)
- return;
- this.packageName = (string)data[0];
- this.packagePath = (string)data[1];
- this.componentName = (string)data[2];
- if ((bool)data[3])
- _captured = false;
- }
- public int EM_sortingOrder
- {
- get { return sortingOrder; }
- }
- public void EM_BeforeUpdate()
- {
- if (_renderer == null)
- _renderer = this.GetComponent<Renderer>();
- if (_renderer != null && _renderer.sharedMaterial.mainTexture != _texture)
- _renderer.sharedMaterial.mainTexture = _texture;
- if (packageName != null && componentName != null && !_captured)
- CaptureInEditMode();
- }
- public void EM_Update(UpdateContext context)
- {
- if (_renderer != null)
- _renderer.sortingOrder = context.renderingOrder++;
- }
- public void EM_Reload()
- {
- _captured = false;
- }
- #endregion
- }
- }
|