NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Framework/UI/UIWindow.cs

581 lines
15 KiB
C#
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using Cysharp.Threading.Tasks;
using Framework;
using PhxhSDK;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using UnityEngine.Serialization;
using Object = System.Object;
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代表左右的偏移量
private bool _isNeedScreenAdaption;
// 是否播放默认的打开对话框的声音
public bool isPlayDefaultOpenAudio = true;
// 是否播放默认的关闭对话框的声音
public bool isPlayDefaultCloseAudio = true;
public string WindowName
{
set { mWindowName = value; }
get { return mWindowName; }
}
[HideInInspector]
public UIWindowLayer uiWindowLayer;
[HideInInspector]
private bool isOpen = false;
private bool _isHideAndPush = false;
protected void RegisterScreenAdaption()
{
_lastOrientation = Screen.orientation;
InitScreenUIOffset();
UpdateScreenAdaption();
_isNeedScreenAdaption = true;
}
protected virtual void OnUpdate()
{
if (_isNeedScreenAdaption && _lastOrientation != Screen.orientation)
{
//Debug.Log("Screen orientation has changed!");
// 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
/// <summary>
/// 屏幕适配,目前方案是左右固定名称的节点下的各个物体需要适配,其他的不管
/// </summary>
protected void UpdateScreenAdaption()
{
var goLeft = transform.Find("UI_LiuHaiLeft")?.gameObject;
var goRight = transform.Find("UI_LiuHaiRight")?.gameObject;
if (goLeft)
{
var rectTrans = goLeft.GetComponent<RectTransform>();
var originPos = rectTrans.anchoredPosition;
rectTrans.anchoredPosition = new Vector2(_offsets.x, originPos.y);
}
if (goRight)
{
var rectTrans = goRight.GetComponent<RectTransform>();
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<RectTransform>();
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<RectTransform>();
var originPos = rectTrans.anchoredPosition;
SetScreenOffsets(new Vector2(_offsets.x, originPos.x - offset.y));
}
}
#endregion
public void OpenWindow(object data = null)
{
PreLoad(data);
if (!isOpen)
{
OnInit();
}
Show(data);
if (isPlayDefaultOpenAudio)
{
//AudioManager3.Instance.PlaySound("");
}
}
public void CloseWindow(UIWindowCloseType closeType = UIWindowCloseType.HideAndDestroy)
{
if (isPlayDefaultCloseAudio && isOpen)
{
//AudioManager3.Instance.PlaySound("");
}
if (closeType == UIWindowCloseType.HideAndDestroy)
{
var last = UIManager.Instance.GetLast();
if (last == this)
{
UIManager.Instance.PopWindow();
}
_OnClose();
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<bool> OnBack(object data = null)
{
var window = UIManager.Instance.PopWindow();
if (window == null)
{
CloseWindow(UIWindowCloseType.HideAndDestroy);
return true;
}
await UIManager.AnimSwitchWindow(this, UIWindowCloseType.HideAndDestroy, window, data);
return true;
}
public void ReloadWindow(object data)
{
if (isOpen)
{
OnReloadWindow(data);
return;
}
Show(data);
OnReloadWindow(data);
}
public bool IsOpen()
{
return isOpen;
}
private void Show(object data)
{
var toTrue = (isOpen == false);
isOpen = true;
_isHideAndPush = false;
if (gameObject == null)
{
DebugUtil.Log("UI已被销毁:{0}", WindowName);
}
else
{
gameObject.SetActive(true);
}
// if (toTrue)
// {
OnShowWindow(data);
//}
}
private void ShowAgain()
{
gameObject.SetActive(true);
//OnShow();
}
private void Hide(bool isOnlyHide = false)
{
gameObject.SetActive(false);
if (!isOnlyHide)
{
OnHideWindow();
_isHideAndPush = 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.OpenWindow();
if (UIManager.Instance.CheckWindowIsFullScreen(latestWindow))
break;
}
}
else
{
UIManager.Instance.ForceRemoveWindow(this);
}
}
private void DestroyWindow()
{
if (isOpen)
{
OnHideWindow();
OnRelease();
}
isOpen = false;
UnityEngine.Object.Destroy(gameObject);
AssetManager.Instance.Unload(string.Format(UIManager.UI_PREFAB_PATH, mWindowName));
}
/// <summary>
///预加载,传入参数,不能添加监听
/// </summary>
public virtual void PreLoad(object data = null)
{
}
/// <summary>
/// 打开界面时调用
/// </summary>
/// <param name="data"></param>
protected virtual void OnShowWindow(object data) { }
//protected virtual void OnOpenWindow() { }
/// <summary>
/// 关闭界面时调用
/// </summary>
protected virtual void OnHideWindow() { }
/// <summary>
/// 重新加载界面时调用
/// </summary>
protected virtual void OnReloadWindow(object data) { }
/// <summary>
/// 私有Awake方法会在基类Awake执行后调用
/// </summary>
public abstract void OnInit();
/// <summary>
/// 对应OnInit在销毁掉界面时调用
/// </summary>
public virtual void OnRelease(){}
#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<Button>();
if (button != null)
{
button.onClick.AddListener
(
delegate ()
{
if (playAudio)
{
//AudioManager.Instance.PlaySound(SfxNameConst.button_s);
}
action?.Invoke();
}
);
}
}
else
{
DebugUtil.LogError("未找到 {0}/{1}", gameObject.name, target);
}
return obj;
}
//增加一个可绑定对应变量的点击事件
//传入GameObject
public GameObject BindButton(GameObject obj, Action action, bool playAudio = true)
{
if (obj != null)
{
Button button = obj.GetComponent<Button>();
if (button != null)
{
button.onClick.AddListener
(
delegate ()
{
if (playAudio)
{
//AudioManager.Instance.PlaySound(SfxNameConst.button_s);
}
action?.Invoke();
}
);
}
}
else
{
DebugUtil.LogError("未找到 {0}/{1}", gameObject.name, obj.name);
}
return obj;
}
//传入参数
public GameObject BindButton<T>(GameObject obj, Action<T> action, T parameter, bool playAudio = true)
{
if (obj != null)
{
Button button = obj.GetComponent<Button>();
if (button != null)
{
button.onClick.AddListener
(
delegate ()
{
if (playAudio)
{
//AudioManager.Instance.PlaySound(SfxNameConst.button_s);
}
action?.Invoke(parameter);
}
);
}
}
else
{
DebugUtil.LogError("未找到 {0}/{1}", gameObject.name, obj.name);
}
return obj;
}
//直接绑按钮
public GameObject BindButton(Button button, Action action, bool playAudio = true)
{
if (button != null)
{
//Button button = button.GetComponent<Button>();
if (button != null)
{
button.onClick.AddListener
(
delegate ()
{
if (playAudio)
{
//AudioManager.Instance.PlaySound(SfxNameConst.button_s);
}
action?.Invoke();
}
);
}
}
else
{
DebugUtil.LogError("传入按钮为空,请检查按钮绑定参数!!!");
//DebugUtil.LogError($"未找到 {gameObject.name}/{button.name}");
return null;
}
return button.gameObject;
}
//可传入参数
public GameObject BindButton<T>(Button button, Action<T> action, T parameter, bool playAudio = true)
{
if (button != null)
{
//Button button = obj.GetComponent<Button>();
if (button != null)
{
button.onClick.AddListener
(
delegate ()
{
if (playAudio)
{
//AudioManager.Instance.PlaySound(SfxNameConst.button_s);
}
if (parameter == null)
{
DebugUtil.LogError("=== 传入参数为空! ===");
}
action?.Invoke(parameter);
}
);
}
}
else
{
DebugUtil.LogError("传入按钮为空,请检查按钮绑定参数!!!");
return null;
}
return button.gameObject;
}
public void ClearBind(Button button)
{
if (button != null)
{
button.onClick.RemoveAllListeners();
}
}
public void ClearBind(GameObject go)
{
var button = go.GetComponent<Button>();
if (button != null)
{
button.onClick.RemoveAllListeners();
}
}
public GameObject FindObj(string path)
{
GameObject obj = transform.Find(path)?.gameObject;
if (obj == null)
{
DebugUtil.LogError("{0}未找到 {1}/{2}", mWindowName, gameObject.name, path);
}
return obj;
}
public T GetComponent<T>(string path = "") where T : Behaviour
{
var component = transform.Find(path)?.GetComponent<T>();
if (component == null)
{
DebugUtil.LogError("{0}未找到组件{1} {2}", mWindowName, typeof(T).Name, path);
}
return component;
}
#endregion
public void HideWindow(bool isOnlyHide = false)
{
Hide(isOnlyHide);
}
public void ShowWindow()
{
ShowAgain();
}
#region #Anim
public async UniTask PlayAnimation(string name)
{
}
public async UniTask AnimShow()
{
await PlayAnimation(DEFAULT_SHOW_ANIM);
}
public async UniTask AnimHide()
{
await PlayAnimation(DEFAULT_HIDE_ANIM);
}
#endregion
}