336 lines
9.8 KiB
C#
336 lines
9.8 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
|
|
}
|
|
}
|