using System; using System.Collections.Generic; using Cysharp.Threading.Tasks; using DG.Tweening; using Framework; using PhxhSDK; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; using UnityEngine.Serialization; using Object = System.Object; using UniTask = Cysharp.Threading.Tasks.UniTask; public abstract class UIWindow { public GameObject gameObject; public Transform transform; public RectTransform rectTransform; public string name; private const string DEFAULT_SHOW_ANIM = "show"; private const string DEFAULT_HIDE_ANIM = "hide"; private string mWindowName; private ScreenOrientation _lastOrientation; private Vector2 _offsets; //x,y代表左右的偏移量 protected Dictionary AsyncLoadedAssetList = new (); private bool _isNeedScreenAdaption; private bool _bDoNotSetMainCamera = false; //不设置主相机 public bool IsNotSetMainCamera => _bDoNotSetMainCamera; // 是否播放默认的打开对话框的声音 public bool isPlayDefaultOpenAudio = true; // 是否播放默认的关闭对话框的声音 public bool isPlayDefaultCloseAudio = true; private bool _isPlayingOpenAnim; private Sequence _openAnimSeq; public bool IsShowOpenAnim; public string WindowName { set { mWindowName = value; } get { return mWindowName; } } [HideInInspector] public UIWindowLayer uiWindowLayer; [HideInInspector] protected bool isCreated = false; protected bool _isShow = false; protected bool _isHide = false; protected void RegisterScreenAdaption() { _lastOrientation = Screen.orientation; InitScreenUIOffset(); UpdateScreenAdaption(); _isNeedScreenAdaption = true; } public async UniTask LoadAssetAsync(string path) where T : UnityEngine.Object { var asset = await AssetManager.Instance.LoadAssetAsync(path); if (!AsyncLoadedAssetList.ContainsKey(path)) { AsyncLoadedAssetList.Add(path, 1); } else { AsyncLoadedAssetList[path]++ ; } return asset; } public T LoadAsset(string path) where T : UnityEngine.Object { var asset = AssetManager.Instance.LoadAsset(path); return asset; } /// /// 异步预加载 /// /// public async UniTask PostPreload(string path) where T : UnityEngine.Object { await AssetManager.Instance.PostPreload(path); if (!AsyncLoadedAssetList.ContainsKey(path)) AsyncLoadedAssetList.Add(path, 1); else AsyncLoadedAssetList[path]++; } public T GetPreLoadResult(string path) where T : UnityEngine.Object { return AssetManager.Instance.GetPreLoadResult(path); } protected void UnLoad() { foreach (var asset in AsyncLoadedAssetList) { var path = asset.Key; var count = asset.Value; for (int i = 0; i < count; i++) { AssetManager.Instance.Unload(path); } } AsyncLoadedAssetList.Clear(); } protected virtual void OnUpdate() { if (_isNeedScreenAdaption && _lastOrientation != Screen.orientation) { // Add your orientation-specific actions here // Update the last orientation for the next frame _lastOrientation = Screen.orientation; UpdateScreenAdaption(); //左右分别找到指定节点移动,当前的方案 //刘海屏适配 } } public void Update() { OnUpdate(); } #region MonoBehaviour Methods Override protected void Destroy(GameObject obj) { UnityEngine.Object.Destroy(obj); } protected void DestroyImmediate(GameObject obj) { UnityEngine.Object.DestroyImmediate(obj); } protected void Destroy(Component cmp) { UnityEngine.Object.Destroy(cmp); } protected void DestroyImmediate(Component cmp) { UnityEngine.Object.DestroyImmediate(cmp); } protected GameObject Instantiate(GameObject prefab) { return UnityEngine.Object.Instantiate(prefab, transform); } protected GameObject Instantiate(GameObject prefab, Transform trans) { return UnityEngine.Object.Instantiate(prefab, trans); } #endregion #region #ScreenAdaption /// /// 屏幕适配,目前方案是左右固定名称的节点下的各个物体需要适配,其他的不管 /// protected void UpdateScreenAdaption() { var goLeft = transform.Find("UI_LiuHaiLeft")?.gameObject; var goRight = transform.Find("UI_LiuHaiRight")?.gameObject; if (goLeft) { var rectTrans = goLeft.GetComponent(); var originPos = rectTrans.anchoredPosition; rectTrans.anchoredPosition = new Vector2(_offsets.x, originPos.y); } if (goRight) { var rectTrans = goRight.GetComponent(); var originPos = rectTrans.anchoredPosition; rectTrans.anchoredPosition = new Vector2(_offsets.y, originPos.y); } } protected void SetScreenOffsets(Vector2 offset) { _offsets = offset; } protected void InitScreenUIOffset() { var offset = DeviceHelper.GetWidthOffset(); var goLeft = transform.Find("UI_LiuHaiLeft")?.gameObject; if (goLeft) { var rectTrans = goLeft.GetComponent(); var originPos = rectTrans.anchoredPosition; SetScreenOffsets(new Vector2(originPos.x + offset.x, 0)); } GameObject goRight = transform.Find("UI_LiuHaiRight")?.gameObject; if (goRight) { var rectTrans = goRight.GetComponent(); var originPos = rectTrans.anchoredPosition; SetScreenOffsets(new Vector2(_offsets.x, originPos.x - offset.y)); } } #endregion #region Window Life public void CreateWindow(object data = null, bool isNotSetCamera = false) { _bDoNotSetMainCamera = isNotSetCamera; PreLoad(data); if (!isCreated) { OnInit(); isCreated = true; } _isShow = false; _isHide = false; IsShowOpenAnim = UIManager.Instance.GetIsAutoPlayAnim(WindowName); Show(data); if (isPlayDefaultOpenAudio) { //AudioManager3.Instance.PlaySound(""); } } /// /// 关闭窗口 /// /// /// 强制设置动画,0不管,1强制开,-1强制不开 /// public async void CloseWindow(UIWindowCloseType closeType = UIWindowCloseType.HideAndDestroy, int forceShowAnim = 0, bool isOpenMainCamera = true) { // if (UIManager.Instance.CheckWindowIsFullScreen(this)) // { // CameraManager.Instance.SetMainCameraActive(isOpenMainCamera); // } if (UIManager.Instance.CheckWindowIsFullScreen(this)) { if (!_bDoNotSetMainCamera) { CameraManager.Instance.SetMainCameraActive(isOpenMainCamera); } } if (isPlayDefaultCloseAudio && isCreated) { //AudioManager3.Instance.PlaySound(""); } if (closeType == UIWindowCloseType.HideAndDestroy) { var last = UIManager.Instance.GetLast(); if (last == this) { UIManager.Instance.PopWindow(); } bool isShowCloseAnim = IsShowOpenAnim; if (forceShowAnim > 0) { isShowCloseAnim = true; } if (forceShowAnim < 0) { isShowCloseAnim = false; } _OnClose(); if (isShowCloseAnim) { await AnimHide(() => { DestroyWindow(); UIManager.Instance.RemoveWindow(mWindowName); }); } else { DestroyWindow(); UIManager.Instance.RemoveWindow(mWindowName); } } else if(closeType == UIWindowCloseType.OnlyHide) { Hide(); } else if(closeType == UIWindowCloseType.HideAndPush) { Hide(); //UIManager.Instance.PushWindow(this); } else { //强制清除所有界面时使用 DestroyWindow(); UIManager.Instance.RemoveWindow(mWindowName); } } public virtual async UniTask OnBack(object data = null) { if (UIManager.Instance.GetLast() != null) { OnDirectBack(); return true; } await OnBackApp(); return true; } protected void OnDirectBack() { CloseWindow(); } protected async UniTask OnBackApp() { await UIManager.Instance.CreateAndOpenWindow(UINameConst.UIBackReturn); } public void ReloadWindow(object data) { if (isCreated) { OnReloadWindow(data); return; } Show(data); OnReloadWindow(data); } public bool IsCreated() { return isCreated; } public bool IsShow() { return _isShow; } public bool IsHide() { return _isHide; } private async void Show(object data) { // var toTrue = (isCreated == false); // isCreated = true; if (gameObject == null) { DebugUtil.Log("UI已被销毁:{0}", WindowName); } else { if (IsShowOpenAnim) { var canvasGroup = gameObject.GetComponent(); if (!canvasGroup) { canvasGroup = gameObject.AddComponent(); } canvasGroup.alpha = 0; } gameObject.SetActive(true); if (IsShowOpenAnim) { await AnimShow(); } } // if (toTrue) // { if (UIManager.Instance.WindowInfos.TryGetValue(WindowName, out var windowInfo)) { // if (windowInfo.UIOpenType == UIOpenType.FullScreen) // { // if (CameraManager.Instance.CheckMainCameraIsActive()) // { // CameraManager.Instance.SetMainCameraActive(false); // } // } if (CameraManager.Instance.CheckMainCameraIsActive()) { if (windowInfo.UIOpenType == UIOpenType.FullScreen) { //特殊处理主界面 if (!_bDoNotSetMainCamera && WindowName != UINameConst.UI_MainPanel) { CameraManager.Instance.SetMainCameraActive(false); } } } } OnShowWindow(data); _isShow = true; _isHide = false; //} } private void ShowAgain() { if (gameObject) { gameObject.SetActive(true); } //OnShow(); } private void Hide(bool isOnlyHide = false) { gameObject?.SetActive(false); //isOpen = false; if (!isOnlyHide) { OnHideWindow(); _isHide = true; _isShow = false; if (UIManager.Instance.WindowInfos.TryGetValue(WindowName, out var windowInfo)) { if (windowInfo.UIOpenType == UIOpenType.FullScreen) { if (!CameraManager.Instance.CheckMainCameraIsActive()) { CameraManager.Instance.SetMainCameraActive(true); } } } } } private void _OnClose() { if (UIManager.Instance.UiWindowStack.Count <= 0) { return; } if (UIManager.Instance.CheckWindowIsFullScreen(this)) { var window = UIManager.Instance.GetLastFullScreen(); if (window != null && window != this) { if (UIManager.Instance.CheckIsWindowInStack(this)) { UIManager.Instance.ForceRemoveWindow(this); } } for (int i = UIManager.Instance.UiWindowStack.Count - 1; i >= 0; i--) { var latestWindow = UIManager.Instance.UiWindowStack[i]; latestWindow.ShowWindow(); if (UIManager.Instance.CheckWindowIsFullScreen(latestWindow)) break; } } else { UIManager.Instance.ForceRemoveWindow(this); } } private void DestroyWindow() { OnHideWindow(); if (isCreated) { OnRelease(); isCreated = false; } UIManager.Instance.UIWindowObjDic.Remove(gameObject); UnityEngine.Object.Destroy(gameObject); AssetManager.Instance.Unload(string.Format(UIManager.UI_PREFAB_PATH, mWindowName)); } #endregion #region Framework /// ///预加载,传入参数,不能添加监听 /// public virtual void PreLoad(object data = null) { } /// /// 打开界面时调用 /// /// protected virtual void OnShowWindow(object data) { EventManager.Instance.Send(EventManager.EventName.UIOpen, WindowName); } //protected virtual void OnOpenWindow() { } /// /// 关闭界面时调用 /// protected virtual void OnHideWindow() { EventManager.Instance.Send(EventManager.EventName.UIClose, WindowName); } /// /// 重新加载界面时调用 /// protected virtual void OnReloadWindow(object data) { } /// /// 私有Awake方法,会在基类Awake执行后调用 /// public abstract void OnInit(); /// /// 对应OnInit,在销毁掉界面时调用 /// public virtual void OnRelease() { UnLoad(); _openAnimSeq?.Kill(); } #region #Bind Component public GameObject BindButton(string target, Action action, bool playAudio = true) { GameObject obj = transform.Find(target)?.gameObject; if (obj != null) { Button button = obj.GetComponent