| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- using UnityEngine;
- using UnityEngine.UI;
- using System;
- using UnityEngine.Events;
- using System.Collections.Generic;
- namespace WXB
- {
- [RequireComponent(typeof(RectTransform))]
- [RequireComponent(typeof(CanvasRenderer))]
- [ExecuteInEditMode]
- public class DrawObject : MonoBehaviour, Draw, IClippable, ICanvasElement
- {
- private RectMask2D m_ParentMask;
- [Serializable]
- public class CullStateChangedEvent : UnityEvent<bool> { }
- // Event delegates triggered on click.
- [SerializeField]
- private CullStateChangedEvent m_OnCullStateChanged = new CullStateChangedEvent();
- /// <summary>
- /// Callback issued when culling changes.
- /// </summary>
- /// <remarks>
- /// Called whene the culling state of this MaskableGraphic either becomes culled or visible. You can use this to control other elements of your UI as culling happens.
- /// </remarks>
- public CullStateChangedEvent onCullStateChanged
- {
- get { return m_OnCullStateChanged; }
- set { m_OnCullStateChanged = value; }
- }
- private Canvas m_Canvas;
- /// <summary>
- /// A reference to the Canvas this Graphic is rendering to.
- /// </summary>
- /// <remarks>
- /// In the situation where the Graphic is used in a hierarchy with multiple Canvases, the Canvas closest to the root will be used.
- /// </remarks>
- public Canvas canvas
- {
- get
- {
- if (m_Canvas == null)
- CacheCanvas();
- return m_Canvas;
- }
- }
- private void CacheCanvas()
- {
- var list = ListPool<Canvas>.Get();
- gameObject.GetComponentsInParent(false, list);
- if (list.Count > 0)
- {
- // Find the first active and enabled canvas.
- for (int i = 0; i < list.Count; ++i)
- {
- if (list[i].isActiveAndEnabled)
- {
- m_Canvas = list[i];
- break;
- }
- }
- }
- else
- {
- m_Canvas = null;
- }
- ListPool<Canvas>.Release(list);
- }
- readonly Vector3[] m_Corners = new Vector3[4];
- private Rect rootCanvasRect
- {
- get
- {
- if (rectTransform == null)
- {
- return new Rect(Vector2.zero, Vector2.zero);
- }
- rectTransform.GetWorldCorners(m_Corners);
- if (canvas)
- {
- Matrix4x4 mat = canvas.rootCanvas.transform.worldToLocalMatrix;
- for (int i = 0; i < 4; ++i)
- m_Corners[i] = mat.MultiplyPoint(m_Corners[i]);
- }
- // bounding box is now based on the min and max of all corners (case 1013182)
- Vector2 min = m_Corners[0];
- Vector2 max = m_Corners[0];
- for (int i = 1; i < 4; i++)
- {
- min.x = Mathf.Min(m_Corners[i].x, min.x);
- min.y = Mathf.Min(m_Corners[i].y, min.y);
- max.x = Mathf.Max(m_Corners[i].x, max.x);
- max.y = Mathf.Max(m_Corners[i].y, max.y);
- }
- return new Rect(min, max - min);
- }
- }
- protected virtual void OnTransformParentChanged()
- {
- if (!isActiveAndEnabled)
- return;
- UpdateRect(Vector2.zero);
- UpdateClipParent();
- }
- protected virtual void OnDisable()
- {
- if (canvasRenderer == null)
- return;
- canvasRenderer.Clear();
- UpdateClipParent();
- }
- protected void OnEnable()
- {
- UpdateRect(Vector2.zero);
- UpdateClipParent();
- }
- public void OnInit()
- {
- enabled = true;
- UpdateRect(Vector2.zero);
- }
- protected void Start()
- {
- UpdateRect(Vector2.zero);
- }
- protected virtual void Init()
- {
- }
- protected void Awake()
- {
- canvasRenderer = GetComponent<CanvasRenderer>();
- rectTransform = GetComponent<RectTransform>();
- Init();
- }
- public RectTransform rectTransform { get; private set; }
- public virtual DrawType type { get { return DrawType.Default; } }
- public virtual long key { get; set; }
- public CanvasRenderer canvasRenderer
- {
- get;
- private set;
- }
- protected void UpdateRect(Vector2 offset)
- {
- Tools.UpdateRect(rectTransform, offset);
- }
- public virtual void UpdateSelf(float deltaTime)
- {
- }
- Material m_Material;
- Texture m_Texture;
- public Material srcMat { get { return m_Material; } set { m_Material = value; } }
- public Texture texture
- {
- get { return m_Texture; }
- set { m_Texture = value; }
- }
- public void FillMesh(Mesh workerMesh)
- {
- canvasRenderer.SetMesh(workerMesh);
- }
- public virtual void UpdateMaterial(Material mat)
- {
- canvasRenderer.materialCount = 1;
- canvasRenderer.SetMaterial(mat, 0);
- canvasRenderer.SetTexture(m_Texture);
- }
- public virtual void Release()
- {
- m_Material = null;
- m_Texture = null;
- key = 0;
- if (canvasRenderer != null)
- {
- canvasRenderer.Clear();
- }
- }
- public void DestroySelf()
- {
- Tools.Destroy(gameObject);
- }
- private void UpdateClipParent()
- {
- var newParent = MaskUtilities.GetRectMaskForClippable(this);
- // if the new parent is different OR is now inactive
- if (m_ParentMask != null && (newParent != m_ParentMask || !newParent.IsActive()))
- {
- m_ParentMask.RemoveClippable(this);
- UpdateCull(false);
- }
- // don't re-add it if the newparent is inactive
- if (newParent != null && newParent.IsActive())
- newParent.AddClippable(this);
- m_ParentMask = newParent;
- }
- /// <summary>
- /// See IClippable.RecalculateClipping
- /// </summary>
- public virtual void RecalculateClipping()
- {
- UpdateClipParent();
- }
- /// <summary>
- /// See IClippable.Cull
- /// </summary>
- public virtual void Cull(Rect clipRect, bool validRect)
- {
- var cull = !validRect || !clipRect.Overlaps(rootCanvasRect, true);
- UpdateCull(cull);
- }
- private void UpdateCull(bool cull)
- {
- if (canvasRenderer == null) return;
- if (canvasRenderer.cull != cull)
- {
- canvasRenderer.cull = cull;
- UISystemProfilerApi.AddMarker("MaskableGraphic.cullingChanged", this);
- m_OnCullStateChanged.Invoke(cull);
- //OnCullingChanged();
- if (!canvasRenderer.cull && !CanvasUpdateRegistry.IsRebuildingGraphics() && !CanvasUpdateRegistry.IsRebuildingLayout())
- {
- /// When we were culled, we potentially skipped calls to <c>Rebuild</c>.
- CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);
- }
- }
- }
- /// <summary>
- /// See IClippable.SetClipRect
- /// </summary>
- public virtual void SetClipRect(Rect clipRect, bool validRect)
- {
- if (canvasRenderer == null) return;
- if (validRect)
- canvasRenderer.EnableRectClipping(clipRect);
- else
- canvasRenderer.DisableRectClipping();
- }
- public virtual void Rebuild(CanvasUpdate executing)
- {
-
- }
- public virtual void LayoutComplete()
- {
-
- }
- public virtual void GraphicUpdateComplete()
- {
-
- }
- public virtual bool IsDestroyed()
- {
- return this == null;
- }
- public void SetClipSoftness(Vector2 clipSoftness)
- {
-
- }
- }
- }
|