using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; using System.Collections; using System.Collections.Generic; public class WindowSign : MonoBehaviour { private List<UIParticleSystem> m_UIParticles = new List<UIParticleSystem>(); private int m_uiType = 0; private Canvas m_Canvas = null; private GraphicRaycaster m_Raycaster = null; private bool m_Dirty = false; public bool _IsNeedAddCanvas = false; public int UIType = 0; private void Awake() { if(m_uiType == 0 && _IsNeedAddCanvas) m_uiType = UIType; } //Window的层级计算公式 public int SortingOrder { get { int siblingIndex = transform.GetSiblingIndex(); return m_uiType * 10000 + siblingIndex; } } private bool ObjectValit(Component component) { return component != null && component.gameObject != null && component.gameObject.activeInHierarchy; } public bool UIParticlesEnable() { for(int i=0;i< m_UIParticles.Count;i++) { if (ObjectValit(m_UIParticles[i])) return true; } return false; } //窗口中是否有特效 public bool IsUIParticleIn { get { return UIParticlesEnable() || _IsNeedAddCanvas; } } public void Init(int UIType) { m_uiType = UIType; SetWndDirty(); } void OnEnable() { if (m_uiType >= 0) SetWndDirty(); } void Update() { if(m_Dirty) { FreshWnd(); m_Dirty = false; } } //重新检查窗口下的特效,并进行Canvas排序 private void FreshWnd() { if (mStatic_WindowSigns.Contains(this) == false) { mStatic_WindowSigns.Add(this); } m_UIParticles.Clear(); UIParticleSystem[] childs = gameObject.GetComponentsInChildren<UIParticleSystem>(true); m_UIParticles.AddRange(childs); if (m_uiType >= 0) Static_ReSortWindow(); } //设置Window需要重新刷新 public void SetWndDirty() { m_Dirty = true; } void OnDisable() { mStatic_WindowSigns.Remove(this); if (m_uiType >= 0) Static_ReSortWindow(); } public void SortSelfCavas(int order,int LastRoder) { Canvas[] childs = gameObject.GetComponentsInChildren<Canvas>(true); for(int i=1;i<childs.Length;i++) { int renderroder = childs[i].sortingOrder; if (order < 0 && renderroder + order < 0) continue; if (renderroder >= LastRoder) renderroder = order + (renderroder - LastRoder); else renderroder += order; childs[i].sortingOrder = renderroder > 0 ? renderroder : 0; } } public void SortUIParticle(int order) { for(int i=0;i<m_UIParticles.Count;i++) { if(ObjectValit(m_UIParticles[i])) { m_UIParticles[i].SortParticle(order); } } } public void AddCanvasComponent(int orderIndex = 2) { int lastCanvasOrder = 0; if (m_Canvas == null) { m_Canvas = gameObject.EnsureComponent<Canvas>(); m_Canvas.sortingOrder = 0; } if (m_Canvas != null) { m_Canvas.overrideSorting = true; lastCanvasOrder = m_Canvas.sortingOrder; m_Canvas.sortingOrder = orderIndex; } if (m_Raycaster == null) m_Raycaster = gameObject.EnsureComponent<GraphicRaycaster>(); SetLayer(UIManager.Instance().gameObject.layer); SortUIParticle(orderIndex); SortSelfCavas(orderIndex , lastCanvasOrder); } public void SetLayer(int layer) { gameObject.layer = layer; Transform[] allChilds = GetComponentsInChildren<Transform>(); for (int i = 0; i < allChilds.Length; i++) { allChilds[i].gameObject.layer = layer; } } public void RemoveCanvas() { if (m_Raycaster != null) { m_Raycaster.enabled = false; Object.DestroyImmediate(m_Raycaster); m_Raycaster = null; } if (m_Canvas != null) { SortUIParticle(-1 * m_Canvas.sortingOrder); SortSelfCavas(-1 * m_Canvas.sortingOrder,0); m_Canvas.enabled = false; Object.DestroyImmediate(m_Canvas); m_Canvas = null; } } //静态数据 private static List<WindowSign> mStatic_WindowSigns = new List<WindowSign>(); public static void Static_ReSortWindow() { mStatic_WindowSigns.Sort((wnd1, wnd2) => { if (wnd1.SortingOrder < wnd2.SortingOrder) return -1; else if (wnd1.SortingOrder > wnd2.SortingOrder) return 1; return 0; }); bool IsIn = false; for(int i=0;i<mStatic_WindowSigns.Count;i++) { if(IsIn || mStatic_WindowSigns[i]._IsNeedAddCanvas) { mStatic_WindowSigns[i].AddCanvasComponent(i * 100); //每个窗口预留100个层级给特效 } else { mStatic_WindowSigns[i].RemoveCanvas(); } if(mStatic_WindowSigns[i].IsUIParticleIn) { IsIn = true; } } } }