using System.Collections;
|
using System.Collections.Generic;
|
using UnityEngine;
|
using System;
|
|
namespace vnxbqy.UI
|
{
|
|
public class WindowCenter : SingletonMonobehaviour<WindowCenter>
|
{
|
public event Action<Window> windowBeforeOpenEvent;
|
public event Action<Window> windowAfterOpenEvent;
|
public event Action<Window> windowBeforeCloseEvent;
|
public event Action<Window> windowAfterCloseEvent;
|
public event Action<Window> jumpWindowCloseEvent;
|
|
UIRoot m_UIRoot;
|
public UIRoot uiRoot
|
{
|
get
|
{
|
if (m_UIRoot == null)
|
{
|
var prefab = BuiltInLoader.LoadPrefab("UIRoot");
|
var instance = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity);
|
instance.name = "UIRoot";
|
m_UIRoot = instance.GetComponent<UIRoot>();
|
if (Application.isPlaying)
|
{
|
GameObject.DontDestroyOnLoad(instance);
|
}
|
}
|
return m_UIRoot;
|
}
|
}
|
|
WindowAsyncLoad m_AnyncLoad;
|
public WindowAsyncLoad asyncLoad
|
{
|
get
|
{
|
if (m_AnyncLoad == null)
|
{
|
var gameObject = new GameObject("WindowAnyncLoad");
|
m_AnyncLoad = gameObject.AddMissingComponent<WindowAsyncLoad>();
|
GameObject.DontDestroyOnLoad(gameObject);
|
}
|
|
return m_AnyncLoad;
|
}
|
}
|
|
Windows windows = new Windows();
|
List<OpenCommand> openCommands = new List<OpenCommand>();
|
List<CloseCommand> closeCommands = new List<CloseCommand>();
|
|
public T Get<T>() where T : Window
|
{
|
T win = null;
|
if (TryGetWindow(out win))
|
{
|
return win;
|
}
|
else
|
{
|
DebugEx.LogFormat("没有找到窗口:{0}", typeof(T).Name);
|
return null;
|
}
|
|
}
|
|
public Window Get(string name)
|
{
|
WindowTrim(name);
|
if (windows.ContainsKey(name))
|
{
|
return windows[name];
|
}
|
else
|
{
|
return null;
|
}
|
}
|
|
public WindowType GetWindowType(string name)
|
{
|
return windows.GetWindowType(name);
|
}
|
|
public void OpenFromLocal<T>(int functionOrder = 0) where T : Window
|
{
|
var command = new OpenCommand()
|
{
|
name = typeof(T).Name,
|
sync = true,
|
playAnimatioin = false,
|
fromBuiltIn = true,
|
functionOrder = functionOrder
|
};
|
|
PushOpenCommand(command);
|
}
|
|
public void OpenFromLocal(string name)
|
{
|
var command = new OpenCommand()
|
{
|
name = name,
|
sync = true,
|
playAnimatioin = false,
|
fromBuiltIn = true,
|
functionOrder = 0
|
};
|
|
PushOpenCommand(command);
|
}
|
|
public void Open<T>(bool forceSync = false, int functionOrder = 0, string fixParentName = "") where T : Window
|
{
|
var command = new OpenCommand()
|
{
|
name = typeof(T).Name,
|
sync = forceSync,
|
playAnimatioin = true,
|
fromBuiltIn = false,
|
functionOrder = functionOrder,
|
fixParentName = fixParentName
|
};
|
|
PushOpenCommand(command);
|
}
|
|
public void Open(string name, bool forceSync = false, int functionOrder = 0, string fixParentName = "")
|
{
|
var command = new OpenCommand()
|
{
|
name = name,
|
sync = forceSync,
|
playAnimatioin = true,
|
fromBuiltIn = false,
|
functionOrder = functionOrder,
|
fixParentName = fixParentName
|
};
|
|
PushOpenCommand(command);
|
}
|
|
#if UNITY_EDITOR
|
public Dictionary<string, bool> openWinNames = new Dictionary<string, bool>();
|
#endif
|
|
private void PushOpenCommand(OpenCommand command)
|
{
|
#if UNITY_EDITOR
|
//用于工具导出打开的界面的图片
|
openWinNames[command.name] = command.fromBuiltIn;
|
#endif
|
DebugEx.LogFormat("打开窗口:{0} ", command.name);
|
var name = command.name;
|
var index = closeCommands.FindIndex((x) => { return x.name == name; });
|
if (index != -1)
|
{
|
closeCommands.RemoveAt(index);
|
}
|
|
var exist = openCommands.Exists((x) => { return x.name == name; });
|
if (!exist)
|
{
|
openCommands.Add(command);
|
}
|
}
|
|
public void Close<T>() where T : Window
|
{
|
PushCloseCommand(new CloseCommand()
|
{
|
name = typeof(T).Name,
|
});
|
}
|
|
public void Close(string name)
|
{
|
if (WindowConfig.IsChildWindow(name))
|
{
|
CloseImmediately(name);
|
}
|
else
|
{
|
PushCloseCommand(new CloseCommand()
|
{
|
name = name,
|
});
|
}
|
}
|
|
public void CloseImmediately(string name)
|
{
|
Window window;
|
if (windows.TryGetValue(name, out window))
|
{
|
if (window.windowState != Window.WindowState.Closed)
|
{
|
window.CloseImmediately();
|
}
|
}
|
}
|
|
private void PushCloseCommand(CloseCommand command)
|
{
|
var name = command.name;
|
var index = openCommands.FindIndex((x) => { return x.name == name; });
|
if (index != -1)
|
{
|
openCommands.RemoveAt(index);
|
}
|
|
var exist = closeCommands.Exists((x) => { return x.name == name; });
|
if (!exist)
|
{
|
closeCommands.Add(command);
|
}
|
}
|
|
public List<string> GetAll()
|
{
|
return new List<string>(windows.Keys);
|
}
|
|
public void CloseAll(CloseAllIgnoreType ignoreType = CloseAllIgnoreType.BaseAndCustom)
|
{
|
for (var i = windows.Keys.Count - 1; i >= 0; i--)
|
{
|
var name = windows.Keys[i];
|
var window = windows[name];
|
if (window == null)
|
{
|
continue;
|
}
|
|
var isIgnore = false;
|
switch (ignoreType)
|
{
|
case CloseAllIgnoreType.Base:
|
isIgnore = window.windowInfo.windowType <= WindowType.Base;
|
break;
|
case CloseAllIgnoreType.BaseAndCustom:
|
isIgnore = window.windowInfo.windowType <= WindowType.Base || CloseAllIgnoreWindowConfig.IsIgnore(name);
|
break;
|
case CloseAllIgnoreType.System:
|
isIgnore = window.windowInfo.windowType >= WindowType.System;
|
break;
|
case CloseAllIgnoreType.Custom:
|
isIgnore = CloseAllIgnoreWindowConfig.IsIgnore(name);
|
break;
|
case CloseAllIgnoreType.SystemAndCustom:
|
isIgnore = window.windowInfo.windowType >= WindowType.System || CloseAllIgnoreWindowConfig.IsIgnore(name);
|
break;
|
}
|
|
isIgnore = isIgnore || WindowConfig.IsChildWindow(name);
|
if (!isIgnore)
|
{
|
if (window.windowState == Window.WindowState.Opened || window.windowState == Window.WindowState.Opening)
|
{
|
Close(name);
|
}
|
}
|
}
|
|
asyncLoad.StopAllTasks();
|
}
|
|
public void CloseOthers<T>() where T : Window
|
{
|
for (var i = windows.Keys.Count - 1; i >= 0; i--)
|
{
|
var name = windows.Keys[i];
|
var window = windows[name];
|
if (window == null || window is T)
|
{
|
continue;
|
}
|
|
var isIgnore = WindowConfig.IsChildWindow(name);
|
if (isIgnore)
|
{
|
continue;
|
}
|
|
if (window != null)
|
{
|
if (window.windowState == Window.WindowState.Opened || window.windowState == Window.WindowState.Opening)
|
{
|
Close(name);
|
}
|
}
|
}
|
|
asyncLoad.StopAllTasks();
|
}
|
|
public void CloseOthers(List<string> windowNames, CloseAllIgnoreType ignoreType)
|
{
|
for (var i = windows.Keys.Count - 1; i >= 0; i--)
|
{
|
var name = windows.Keys[i];
|
var window = windows[name];
|
if (window == null)
|
{
|
continue;
|
}
|
|
var isIgnore = false;
|
switch (ignoreType)
|
{
|
case CloseAllIgnoreType.Base:
|
isIgnore = windowNames.Contains(name) || window.windowInfo.windowType <= WindowType.Base;
|
break;
|
case CloseAllIgnoreType.BaseAndCustom:
|
isIgnore = windowNames.Contains(name) || window.windowInfo.windowType <= WindowType.Base || CloseAllIgnoreWindowConfig.IsIgnore(name);
|
break;
|
case CloseAllIgnoreType.System:
|
isIgnore = windowNames.Contains(name) || window.windowInfo.windowType >= WindowType.System;
|
break;
|
case CloseAllIgnoreType.Custom:
|
isIgnore = windowNames.Contains(name) || CloseAllIgnoreWindowConfig.IsIgnore(name);
|
break;
|
case CloseAllIgnoreType.SystemAndCustom:
|
isIgnore = windowNames.Contains(name) || window.windowInfo.windowType >= WindowType.System || CloseAllIgnoreWindowConfig.IsIgnore(name);
|
break;
|
}
|
|
isIgnore = isIgnore || WindowConfig.IsChildWindow(name);
|
if (!isIgnore)
|
{
|
if (window.windowState == Window.WindowState.Opened || window.windowState == Window.WindowState.Opening)
|
{
|
Close(name);
|
}
|
}
|
}
|
|
asyncLoad.StopAllTasks();
|
}
|
|
public void DestoryWinsByStage(WindowStage windowStage)
|
{
|
switch (windowStage)
|
{
|
case WindowStage.Launch:
|
DestroyWin<DownLoadWin>();
|
DestroyWin<VersionUpdateWin>();
|
DestroyWin<LaunchWin>();
|
|
if (!AssetSource.uiFromEditor)
|
{
|
AssetBundleUtility.Instance.UnloadAssetBundle("builtin/prefabs", true, false);
|
}
|
break;
|
case WindowStage.Login:
|
DestroyWin<LoginWin>();
|
DestroyWin<ServerListWin>();
|
|
UILoader.UnLoadPriorityWindow("LoginWin");
|
break;
|
case WindowStage.SelectRole:
|
DestroyWin<CreateRoleWin>();
|
DestroyWin<LaunchBackGroundWin>();
|
|
UILoader.UnLoadPriorityWindow("CreateRoleWin");
|
UILoader.UnLoadPriorityWindow("SelectRoleWin");
|
UILoader.UnLoadPriorityWindow("LaunchBackGroundWin");
|
break;
|
default:
|
break;
|
}
|
|
UnLoadAssetBundle(windowStage);
|
}
|
|
public void DestroyWin<T>() where T : Window
|
{
|
DestroyWin(typeof(T).Name);
|
}
|
|
public void DestroyWin(string name)
|
{
|
if (windows.ContainsKey(name))
|
{
|
var win = windows[name];
|
win.CloseImmediately();
|
GameObject.Destroy(win.gameObject, 0.3f);
|
MonoBehaviour.Destroy(win, 0.3f);
|
windows[name] = null;
|
windows.Remove(name);
|
}
|
else
|
{
|
DebugEx.LogFormat("{0} 窗口无法获得!", name);
|
}
|
}
|
|
public void UnLoadAssetBundle(WindowStage windowStage)
|
{
|
if (!AssetSource.uiFromEditor)
|
{
|
switch (windowStage)
|
{
|
case WindowStage.Launch:
|
break;
|
case WindowStage.Login:
|
AssetBundleUtility.Instance.UnloadAsset("ui/prioritywindow", "LoginWin");
|
AssetBundleUtility.Instance.UnloadAsset("ui/prioritywindow", "ServerListWin");
|
break;
|
case WindowStage.SelectRole:
|
AssetBundleUtility.Instance.UnloadAsset("ui/prioritywindow", "CreateRoleWin");
|
AssetBundleUtility.Instance.UnloadAsset("ui/prioritywindow", "SelectRoleWin");
|
break;
|
default:
|
break;
|
}
|
}
|
}
|
|
public bool IsOpen<T>() where T : Window
|
{
|
T win = null;
|
if (TryGetWindow(out win))
|
{
|
var open = win.windowState == Window.WindowState.Opened
|
|| win.windowState == Window.WindowState.Opening;
|
|
return open;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
|
public bool IsOpen(string name)
|
{
|
if (windows.ContainsKey(name) && windows[name] != null)
|
{
|
var window = windows[name];
|
return window.windowState == Window.WindowState.Opened || window.windowState == Window.WindowState.Opening;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
|
public bool ExistAnyFullScreenOrMaskWin()
|
{
|
var exist = false;
|
foreach (var name in windows.Keys)
|
{
|
var window = windows[name];
|
if (window.windowInfo.needMask || window.windowInfo.fullScreen)
|
{
|
if (window.windowState == Window.WindowState.Opened || window.windowState == Window.WindowState.Opening)
|
{
|
exist = true;
|
break;
|
}
|
}
|
}
|
|
return exist;
|
}
|
|
/// <summary>
|
/// 是否存在大于或等于这个层级的全屏或有模糊背景的界面
|
/// </summary>
|
/// <param name="windowType"></param>
|
/// <returns></returns>
|
public bool ExistAnyFullScreenOrMaskWinLEqual(WindowType windowType)
|
{
|
var exist = false;
|
foreach (var name in windows.Keys)
|
{
|
var window = windows[name];
|
if ((window.windowInfo.needMask || window.windowInfo.fullScreen) && window.windowInfo.windowType >= windowType)
|
{
|
if (window.windowState == Window.WindowState.Opened || window.windowState == Window.WindowState.Opening)
|
{
|
exist = true;
|
break;
|
}
|
}
|
}
|
|
return exist;
|
}
|
|
internal void NotifyBeforeOpen<T>(T window) where T : Window
|
{
|
//if (ConfigInitiator.done && window is not MainInterfaceWin && !WindowJumpMgr.Instance.IsJumpState)
|
// CalcMainInterfaceWin();
|
|
if (windowBeforeOpenEvent != null)
|
{
|
windowBeforeOpenEvent(window);
|
}
|
}
|
|
internal void NotifyAfterOpen<T>(T window) where T : Window
|
{
|
if (windowAfterOpenEvent != null)
|
{
|
windowAfterOpenEvent(window);
|
}
|
}
|
|
internal void NotifyBeforeClose<T>(T window) where T : Window
|
{
|
if (windowBeforeCloseEvent != null)
|
{
|
windowBeforeCloseEvent(window);
|
}
|
}
|
|
internal void NotifyAfterClose<T>(T window) where T : Window
|
{
|
if (windowAfterCloseEvent != null)
|
{
|
windowAfterCloseEvent(window);
|
}
|
}
|
|
internal void JumpNotifyAfterClose<T>(T window) where T : Window
|
{
|
//if (ConfigInitiator.done && window is not MainInterfaceWin && !WindowJumpMgr.Instance.IsJumpState)
|
// CalcMainInterfaceWin();
|
checkMainWin = true;
|
if (jumpWindowCloseEvent != null)
|
{
|
jumpWindowCloseEvent(window);
|
}
|
}
|
|
private bool TryGetWindow<T>(out T win) where T : Window
|
{
|
var name = typeof(T).Name;
|
Window window = null;
|
if (TryGetWindow(name, out window))
|
{
|
win = windows[name] as T;
|
return win != null;
|
}
|
else
|
{
|
win = null;
|
return false;
|
}
|
}
|
|
private bool TryGetWindow(string name, out Window win)
|
{
|
WindowTrim(name);
|
if (windows.ContainsKey(name))
|
{
|
win = windows[name];
|
return win != null;
|
}
|
else
|
{
|
win = null;
|
return false;
|
}
|
}
|
|
private void WindowTrim(string name)
|
{
|
if (windows.ContainsKey(name))
|
{
|
if (windows[name] == null || windows[name].gameObject == null)
|
{
|
windows.Remove(name);
|
}
|
}
|
}
|
|
float checkTimer = 0f;
|
private void LateUpdate()
|
{
|
var checkMainWinImmedidately = closeCommands.Count + openCommands.Count > 0;
|
|
if (checkMainWin)
|
{
|
checkMainWinImmedidately = true;
|
checkMainWin = false;
|
}
|
|
while (closeCommands.Count > 0)
|
{
|
var command = closeCommands[0];
|
closeCommands.RemoveAt(0);
|
Window window = null;
|
if (windows.TryGetValue(command.name, out window))
|
{
|
if (window.windowState != Window.WindowState.Closed)
|
{
|
window.CloseImmediately();
|
}
|
}
|
|
asyncLoad.StopTask(command.name);
|
}
|
|
while (openCommands.Count > 0)
|
{
|
var command = openCommands[0];
|
openCommands.RemoveAt(0);
|
Window window = null;
|
if (windows.TryGetValue(command.name, out window))
|
{
|
if (window.windowState == Window.WindowState.Closed)
|
{
|
window.playAnimation = command.playAnimatioin;
|
window.functionOrder = command.functionOrder;
|
window.fixParentName = command.fixParentName;
|
window.Open();
|
}
|
else
|
{
|
DebugEx.LogFormat("{0} 窗口已经打开!", command.name);
|
}
|
}
|
else
|
{
|
ExecuteFirstOpen(command);
|
}
|
|
}
|
|
checkTimer += checkMainWinImmedidately ? 1f : Time.deltaTime;
|
if (checkTimer > 0.2f)
|
{
|
checkTimer = 0f;
|
CalcMainInterfaceWin();
|
}
|
}
|
|
bool checkMainWin = false;
|
|
//主界面的开关默认处理
|
public void CalcMainInterfaceWin()
|
{
|
if (!StageLoad.Instance.isLoading)
|
{
|
var exceptOpen = StageLoad.Instance.stageType == Stage.E_StageType.Dungeon
|
&& !ExistAnyFullScreenOrMaskWinLEqual(WindowType.Base)
|
&& !IsOpen("DefaultDialogueBoxWin")
|
&& !IsOpen("DialogueDuidanceWin")
|
&& !IsOpen("TaskBoxBGMWin")
|
&& !IsOpen("WelcomeWin")
|
&& !IsOpen("HazyRegionDialogueWin")
|
&& !IsOpen("NormalDialogueWin")
|
&& !IsOpen("GuideDialogueWin");
|
|
if (exceptOpen != IsOpen("MainInterfaceWin") && windows.ContainsKey("MainInterfaceWin"))
|
{
|
if (exceptOpen)
|
{
|
windows["MainInterfaceWin"].Open();
|
}
|
else
|
{
|
windows["MainInterfaceWin"].CloseImmediately();
|
}
|
}
|
}
|
}
|
|
|
private void ExecuteFirstOpen(OpenCommand command)
|
{
|
GetWindowPrefab(command, (bool ok, GameObject prefab) =>
|
{
|
if (ok)
|
{
|
CreateWindowInstance(command, prefab);
|
Window window = null;
|
if (windows.TryGetValue(command.name, out window))
|
{
|
window.playAnimation = command.playAnimatioin;
|
window.functionOrder = command.functionOrder;
|
window.fixParentName = command.fixParentName;
|
window.Open();
|
}
|
}
|
});
|
}
|
|
private void GetWindowPrefab(OpenCommand command, Action<bool, GameObject> callBack)
|
{
|
if (command.sync)
|
{
|
var name = command.name;
|
var fromBuiltIn = command.fromBuiltIn;
|
var prefab = fromBuiltIn ? BuiltInLoader.LoadPrefab(name) : UILoader.LoadWindow(name);
|
|
if (callBack != null)
|
{
|
callBack(prefab != null, prefab);
|
}
|
}
|
else
|
{
|
var name = command.name;
|
var task = new WindowAsyncLoad.Task(name, (bool ok, UnityEngine.Object @object) =>
|
{
|
var prefab = @object as GameObject;
|
if (callBack != null)
|
{
|
callBack(prefab != null, prefab);
|
}
|
});
|
|
asyncLoad.PushTask(task);
|
}
|
}
|
|
private void CreateWindowInstance(OpenCommand command, GameObject prefab)
|
{
|
var name = command.name;
|
Window window = null;
|
if (!windows.ContainsKey(name))
|
{
|
prefab.SetActive(false);
|
var instance = GameObject.Instantiate(prefab);
|
|
if (AssetSource.uiFromEditor)
|
{
|
prefab.SetActive(true);
|
}
|
|
if (command.fromBuiltIn)
|
{
|
BuiltInLoader.UnLoadPrefab(name);
|
}
|
else
|
{
|
UILoader.UnLoadWindowAsset(name);
|
}
|
|
window = instance.GetComponent<Window>();
|
instance.name = name;
|
if (window != null)
|
{
|
windows[name] = window;
|
}
|
else
|
{
|
Debug.LogFormat("无法获得 {0} 的资源!", name);
|
}
|
}
|
}
|
|
public struct OpenCommand
|
{
|
public string name;
|
public bool sync;
|
public int functionOrder;
|
public bool playAnimatioin;
|
public bool fromBuiltIn;
|
public string fixParentName;
|
}
|
|
public struct CloseCommand
|
{
|
public string name;
|
}
|
|
public enum WindowStage
|
{
|
Launch,
|
Login,
|
SelectRole,
|
Other,
|
}
|
|
public enum CloseAllIgnoreType
|
{
|
Base = 1,
|
System = 2,
|
Custom = 3,
|
BaseAndCustom = 4,
|
SystemAndCustom = 5,
|
}
|
|
class Windows
|
{
|
Dictionary<string, Window> windows = new Dictionary<string, Window>();
|
List<string> windowKeys = new List<string>();
|
|
public Window this[string key]
|
{
|
get { return windows[key]; }
|
set
|
{
|
windows[key] = value;
|
if (!windowKeys.Contains(key))
|
{
|
windowKeys.Add(key);
|
}
|
}
|
}
|
|
public List<string> Keys { get { return windowKeys; } }
|
|
public bool ContainsKey(string key)
|
{
|
return windowKeys.Contains(key);
|
}
|
|
public bool TryGetValue(string key, out Window window)
|
{
|
return windows.TryGetValue(key, out window);
|
}
|
|
public void Remove(string key)
|
{
|
windows.Remove(key);
|
windowKeys.Remove(key);
|
}
|
|
public WindowType GetWindowType(string key)
|
{
|
if (windows.ContainsKey(key))
|
{
|
return windows[key].windowInfo.windowType;
|
}
|
else
|
{
|
return WindowType.Flag;
|
}
|
}
|
|
}
|
|
}
|
|
}
|
|