You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			336 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C#
		
	
			
		
		
	
	
			336 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C#
		
	
| 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
 | |
|     }
 | |
| }
 |