using System; using System.Collections.Generic; using System.Threading.Tasks; using DG.Tweening; using UnityEngine; using UnityEngine.UI; #if HotUpdate using YooAsset; #endif namespace Stary.Evo.UIFarme { public interface IBasePanel : IController { /// /// UI信息 /// string UIName { get; set; } /// /// 绑定这个面板的实例 /// void Initialize(GameObject panelGo); /// /// 绑定这个面板的实例 /// Task InitializeAsync(GameObject panelGo); /// /// 初始化面板管理器 /// /// void Initialize(IPanelSystem sysytem); /// /// 初始化面板管理器 /// /// Task InitializeAsync(IPanelSystem sysytem); /// /// 虚方法,UI进入时执行的操作,只会执行一次 /// void OnEnter(Action complete = null); /// /// 虚方法,UI退出时执行的操作,只会执行一次 /// void OnExit(float delay = 0f); void OnDestroy(); /// /// 生成/获取一个UI对象 /// /// ui信息 /// Task CreatePanel(string packageName, string panelName); /// /// 销毁一个Ui对象 /// /// void DestoryUI(); void SetPanelParent(Transform parent); } /// ///所有UI面板的父类,包含UI面板的状态信息 /// public abstract class BasePanel : IBasePanel { /// /// UI信息 /// public string UIName { get; set; } public abstract UITweenType TweenType { get; } public abstract UIInstantiateType UIType { get; } /// /// 面板管理器 /// protected IPanelSystem PanelSystem { get; private set; } /// /// 生成的父物体 /// protected Transform panelParent { get; private set; } /// /// 缓存该面板所有的SpriteRenderer /// private Dictionary spriteRendererDict; /// /// 缓存该面板所有的Button,Toggle,Slider,InputField,Dropdown,ScroolBar /// private Dictionary selectableDict; protected GameObject activePanel { get; private set; } protected BasePanel() { spriteRendererDict = new Dictionary(); selectableDict = new Dictionary(); } public virtual void Initialize(GameObject panelGo) { activePanel = panelGo; if (UIType == UIInstantiateType.SpriteNormal) { SpriteRenderer[] spriteRenderers = activePanel.GetComponentsInChildren(true); foreach (SpriteRenderer item in spriteRenderers) { spriteRendererDict[item.name] = item; } }else if(UIType == UIInstantiateType.UINormal){ Selectable[] selectables = activePanel.GetComponentsInChildren(true); foreach (Selectable item in selectables) { selectableDict[item.name] = item; } var canvasGroup = UITool.GetOrAddComponent(activePanel); canvasGroup.alpha = 0f; } } public virtual Task InitializeAsync(GameObject panelGo) { Initialize(panelGo); return Task.CompletedTask; } public virtual void Initialize(IPanelSystem sysytem) { PanelSystem = sysytem; } public virtual Task InitializeAsync(IPanelSystem sysytem) { Initialize(sysytem); return Task.CompletedTask; } public virtual void OnEnter(Action complete = null) { activePanel.SetActive(true); SetCanvasGroupTween(1f, complete); } public virtual void OnExit(float delay = 0f) { SetCanvasGroupTween(0f, () => { activePanel.SetActive(false); }); } public virtual void OnDestroy() { DestoryUI(); } public async Task CreatePanel(string packageName, string panelName) { if (panelParent == null) { Debug.LogWarning($"UnityEvo:parent为空,{panelName}自动设置为root节点下,请检查是否正确!!!!!"); } if (this.activePanel != null) { return activePanel.gameObject; } #if HotUpdate AssetHandle handle = null; if (packageName == null) { handle = YooAssets.LoadAssetAsync(panelName); } else { var package = YooAssets.TryGetPackage(packageName); if (package == null) { handle = YooAssets.LoadAssetAsync(panelName); } else { handle = package.LoadAssetAsync(panelName); } } await handle.Task; activePanel = GameObject.Instantiate(handle.AssetObject as GameObject, panelParent); #else GameObject handle = Resources.Load(panelName); activePanel = GameObject.Instantiate(handle, panelParent); #endif activePanel.name = this.GetType().Name; // if (!activePanel.GetComponentInChildren() && !activePanel.GetComponentInParent()) // { // Debug.LogError($"UnityEvo:panelParent上不存在Canvas组件,{panelName}无法正常运行,进程已中断,请检查!!!!!"); // return null; // } return activePanel; } public void DestoryUI() { if (activePanel != null) { GameObject.Destroy(activePanel); PanelSystem.Get_Dic().Remove(this.GetType().Name); } } public void SetPanelParent(Transform parent) { panelParent = parent; } private void SetCanvasGroup(float alpha) { foreach (var spriteRenderer in spriteRendererDict) { Color c = spriteRenderer.Value.color; c.a = alpha; spriteRenderer.Value.color = c; } } private void SetCanvasGroupTween(float alpha, Action complete = null) { if (UIType == UIInstantiateType.SpriteNormal) { // 创建一个新的序列 Sequence sequence = DOTween.Sequence(); foreach (var spriteRenderer in spriteRendererDict) { if (TweenType == UITweenType.None) { Color c = spriteRenderer.Value.color; c.a = alpha; spriteRenderer.Value.color = c; } else if (TweenType == UITweenType.Fade) { sequence.Join(spriteRenderer.Value.DOFade(alpha, 1f)); } else if (TweenType == UITweenType.Yoyo) { sequence.Join(spriteRenderer.Value.DOFade(alpha, 1f) .SetLoops(2, LoopType.Yoyo)); } } if (TweenType == UITweenType.None) { complete?.Invoke(); } else { sequence.OnComplete(() => complete?.Invoke()); } } else if (UIType == UIInstantiateType.UINormal) { activePanel.SetActive(true); var canvasGroup = activePanel.GetComponent(); canvasGroup.blocksRaycasts = true; if (TweenType == UITweenType.None) { canvasGroup.alpha = alpha; } if (TweenType == UITweenType.Fade) { canvasGroup.DOFade(alpha, 1f).OnComplete(() => { complete?.Invoke(); canvasGroup.blocksRaycasts = false; }); } else if (TweenType == UITweenType.Yoyo) { canvasGroup.DOFade(alpha, 1f).SetLoops(2, LoopType.Yoyo).OnComplete(() => { complete?.Invoke(); }); } else { canvasGroup.DOFade(alpha, 1f).SetLoops(-1).OnComplete(() => { complete?.Invoke(); }); } } } public IArchitecture GetArchitecture() { return PanelSystem.GetArchitecture(); } public enum UITweenType { /// /// 无动画 /// None, /// /// 淡入淡出 /// Fade, /// /// 循环播放 /// Loop, /// /// 往返播放 /// Yoyo, } public enum UIInstantiateType { /// /// 普通面板 /// SpriteNormal, /// /// UI普通面板 /// UINormal } } }