//窗口的层
public enum Layer
{
UI,
EF,
}
//对话框类型
public enum DialogType
{
/// <summary>
/// 用户协议弹窗
/// </summary>
UserHttps,
/// <summary>
/// 确定弹窗
/// </summary>
TooltipBox,
}
//对话框选择结果
public enum ResultDialog
{
Yes,
No,
}
//定义一些委托
public delegate void ReturnResultCallback(ResultDialog result);
public delegate void DoneLoadDialog(GameObject window);
public delegate void DoneOpenWindow(GameObject varWindowObj);
public delegate void DoneSpecialObject(GameObject varSpecial);
//窗口管理类
public class WindowManager
{
private static WindowManager Instance;
public static WindowManager GetInstance()
{
if (Instance == null)
{
Instance = new WindowManager();
}
return Instance;
}
public readonly int MaxHeight = 720;
public readonly int MaxWidht = 1280;
float standard_width = 1280f; //初始宽度
float standard_height = 720f; //初始高度
float device_width = 0f; //当前设备宽度
float device_height = 0f; //当前设备高度
public float adjustor = 0f; //屏幕矫正比例
private const int IntervalDepth = 21;
private const int MaxWindowDepth = 3000;
private const int LoadingDepth = 4000;
GameObject mMakePanle = null;
GameObject mRoot = null;
GameObject mWindowRoot = null;
GameObject mDialogRoot = null;
//GameObject mSpecialObject = null;
GameObject mLoadingObject = null;
/// <summary>
/// 已打开的窗口(注:对窗口进行添加移除一定要同步到mOpenWindowKey集合中、字典集合是保证不了顺序的)
/// </summary>
SortedDictionary<string, GameObject> mOpenWindow = new SortedDictionary<string, GameObject>();
/// <summary>
/// 为保证窗口打开顺序,另用集合存储
/// </summary>
List<string> mOpenWindowKey = new List<string>();
/// <summary>
/// 已打开的弹窗
/// </summary>
SortedDictionary<string, GameObject> mOpenDialog = new SortedDictionary<string, GameObject>();
SortedDictionary<string, GameObject> mSpecial = new SortedDictionary<string, GameObject>();
public List<string> noticeList = null;
public GameObject pRoot
{
get
{
return mRoot;
}
}
public WindowManager()
{
//初始化节点
mRoot = new GameObject("UIObject");
mRoot.transform.position = new Vector3(0, 0, -5);
noticeList = new List<string>();
UIRoot mRootScripts = mRoot.AddComponent<UIRoot>();
mRootScripts.scalingStyle = UIRoot.Scaling.Constrained;
mRootScripts.fitWidth = true;
mRootScripts.fitHeight = false;
GameObject mCameraObject = new GameObject("UICamera");
mCameraObject.transform.SetParent(mRoot.transform);
Camera mCamera = mCameraObject.AddComponent<Camera>();
mCamera.orthographic = true;
mCamera.orthographicSize = 1;
mCamera.cullingMask = LayerMask.GetMask(Layer.UI.ToString());
mCamera.clearFlags = CameraClearFlags.Depth;
mCamera.depth = 2;
mCamera.backgroundColor = new Color(0, 0, 0);
UICamera uiCamera = mCameraObject.AddComponent<UICamera>();
uiCamera.eventType = UICamera.EventType.UI_3D;
uiCamera.transform.localPosition = new Vector3(0, 0, -1000);
mWindowRoot = new GameObject("WindowRoot");
mWindowRoot.AddComponent<UIPanel>();
mWindowRoot.transform.SetParent(mRoot.transform);
mDialogRoot = new GameObject("DialogRoot");
mDialogRoot.transform.SetParent(mRoot.transform);
UIPanel panel = mRoot.AddComponent<UIPanel>();
mMakePanle = new GameObject("MakePanle");
mMakePanle.AddComponent<UIPanel>();
Texture2D texture = Texture2D.whiteTexture;
GameObject textureGameObject = new GameObject("background");
UpdateCamera(uiCamera);
//获取设备宽高
device_width = Screen.width;
device_height = Screen.height;
//计算宽高比例
float standard_aspect = standard_width / standard_height;
float device_aspect = device_width / device_height;
//计算矫正比例
if (device_aspect < standard_aspect)
{
adjustor = standard_aspect / device_aspect;
}
if (device_aspect >= standard_aspect)
{
adjustor = 1;
}
UITexture ui = textureGameObject.AddComponent<UITexture>();
ui.mainTexture = texture;
ui.color = new Color(0, 0, 0, 0.6f);
ui.height = (int)device_height + 5000;
ui.width = (int)device_width + 5000;
NGUITools.AddWidgetCollider(textureGameObject);
mMakePanle.SetActive(false);
textureGameObject.transform.SetParent(mMakePanle.transform);
mMakePanle.transform.SetParent(mWindowRoot.transform);
NGUITools.SetChildLayer(mRoot.transform, LayerMask.NameToLayer(Layer.UI.ToString()));
Object.DontDestroyOnLoad(mRoot);
}
public float screenHeight;
public float screenWidth;
void UpdateCamera(UICamera uiCamera)
{
screenHeight = Screen.height;
screenWidth = Screen.width;
Rect r = new Rect();
if (screenHeight / screenWidth > 0.56f)//更方的屏幕 ipad 1024*768
{
r.width = 1;
r.height = (screenWidth * 0.56f) / screenHeight;
r.x = 0;
r.y = (1 - r.height) / 2f;
}
else if (screenHeight / screenWidth < 0.56f)//更长的屏幕480*854
{
r.width = (screenHeight / 0.56f) / screenWidth;
r.height = 1f;
r.x = (1 - r.width) / 2f;
r.y = 0;
}
else //在可适配区域不做处理480*800 - 480*854之间的
{
r.width = 1;
r.height = 1;
r.x = 0;
r.y = 0f;
}
uiCamera.GetComponent<Camera>().rect = r;
}
/// <summary>
/// 设置loading状态
/// </summary>
/// <param name="state">当前loading状态</param>
/// <param name="makeState">蒙版开关参数</param>
public void SetLoading(bool state, bool makeState)
{
SetLoading(LoadingType.Loading, Vector3.zero, state, makeState);
}
public void SetLoading(LoadingType type, Vector3 postion, bool state, bool makeState)
{
if (mLoadingObject != null)
{
Dialog_Loading loading = mLoadingObject.GetComponent<Dialog_Loading>();
if (loading != null)
{
loading.SetLoadingType(type, postion, makeState);
}
mLoadingObject.SetActive(state);
return;
}
DownloadCallback done = (string filePath, Object obj) =>
{
if (obj == null)
{
return;
}
GameObject SpecialObject = Object.Instantiate(obj as GameObject);
Transform mObject = DetachChildren(SpecialObject);
mLoadingObject = mObject.gameObject;
UIPanel[] panels = mLoadingObject.GetComponentsInChildren<UIPanel>();
for (int i = 0; i < panels.Length; i++)
{
panels[i].depth += LoadingDepth;
}
mObject.transform.SetParent(mWindowRoot.transform);
mObject.transform.localScale = Vector3.one;
Dialog_Loading loading = mObject.GetComponent<Dialog_Loading>();
if (loading != null)
{
loading.SetLoadingType(type, postion, makeState);
}
mLoadingObject.SetActive(state);
};
ResourcesManager.GetInstance().AddResourceDownload(Dialog_Loading.DialogPathName, done);
}
/// <summary>
/// 打开一些特殊处理的窗口(如特效)
/// </summary>
/// <param name="pathName"></param>
/// <param name="callback"></param>
public void OpenSpecial(string varPathName, DoneSpecialObject callback = null)
{
varPathName = varPathName.ToLower();
//如果已打开窗口则直接返回
if (mSpecial.ContainsKey(varPathName))
{
GameObject obj = null;
mSpecial.TryGetValue(varPathName, out obj);
if (callback != null)
{
callback(obj);
}
return;
}
DownloadCallback done = (string filePath, Object obj) =>
{
if (obj == null)
{
return;
}
GameObject SpecialObject = Object.Instantiate(obj as GameObject);
UICamera c = SpecialObject.GetComponentInChildren<UICamera>();
Transform mObject = null;
if (c == null)
{
mObject = SpecialObject.transform;
}
else
{
mObject = DetachChildren(SpecialObject);
}
mObject.transform.SetParent(mWindowRoot.transform);
mSpecial[filePath] = mObject.gameObject;
if (callback != null)
{
callback(mObject.gameObject);
}
};
ResourcesManager.GetInstance().AddResourceDownload(varPathName, done);
}
public void DestroySpecial(string pathName)
{
if (mSpecial.ContainsKey(pathName))
{
GameObject obj = mSpecial[pathName];
if (obj != null)
{
Object.Destroy(obj);
}
}
}
/// <summary>
/// 打开一个窗口 路径以Resources下面的路径为标准
/// </summary>
/// <param name="varPathName"></param>
public void OpenInWindow(string varPathName, DoneOpenWindow varCallback = null)
{
OpenInWindow(varPathName, true, varCallback);
}
public void OpenInWindow(string varPathName, bool isOpenMake, DoneOpenWindow varCallback = null)
{
//统一转小写
varPathName = varPathName.ToLower();
//如果已打开窗口则直接返回
if (mOpenWindow.ContainsKey(varPathName))
{
GameObject obj = null;
mOpenWindow.TryGetValue(varPathName, out obj);
if (varCallback != null)
{
varCallback(obj);
}
return;
}
mOpenWindow.Add(varPathName, null);
mOpenWindowKey.Add(varPathName);
DownloadCallback callback = (string vPathName, Object vObject) =>
{
GameObject source = vObject as GameObject;
if (source == null)
{
mOpenWindow.Remove(vPathName);
mOpenWindowKey.Remove(varPathName);
return;
}
GameObject windowObject = Object.Instantiate(source);
UICamera c = windowObject.GetComponentInChildren<UICamera>();
Transform mObject = null;
if (c == null)
{
mObject = windowObject.transform;
}
else
{
mObject = DetachChildren(windowObject);
}
NGUITools.SetChildLayer(windowObject.transform, LayerMask.NameToLayer(Layer.UI.ToString()));
mObject.SetParent(mWindowRoot.transform);
mOpenWindow[vPathName] = mObject.gameObject;
windowObject.transform.localPosition = Vector2.zero;
windowObject.transform.localScale = Vector3.one;
if (!isOpenMake)
{
mMakePanle.SetActive(false);
}
else
{
SetWindowDepth(mObject);
}
if (varCallback != null)
{
varCallback(mObject.gameObject);
}
};
ResourcesManager.GetInstance().AddResourceDownload(varPathName, callback);
}
/// <summary>
/// 设置新窗口层级
/// </summary>
private void SetWindowDepth(Transform varWindow)
{
//如果有Dialog打开并且激活则直接return
if (IsDialogOpen())
{
return;
}
bool varWindowIsNull = false;
if (varWindow == null)
{
varWindowIsNull = true;
}
int effectiveWindow = 0;
//获取有效的窗口
for (int i = 0; i < mOpenWindowKey.Count; i++)
{
GameObject window = mOpenWindow[mOpenWindowKey[i]];
if (window == null)
{
continue;
}
if (varWindowIsNull)
{
if (mOpenWindowKey.Count - 1 == i)
{
varWindow = window.transform;
}
}
if (window.activeSelf)
{
effectiveWindow++;
}
}
int depth = effectiveWindow * IntervalDepth;
if (depth > MaxWindowDepth)
{
}
if (varWindow == null)
{
mMakePanle.SetActive(false);
return;
}
UIPanel[] panles = varWindow.GetComponentsInChildren<UIPanel>();
for (int i = 0; i < panles.Length; i++)
{
if (effectiveWindow <= 1)
{
panles[i].depth = (panles[i].depth % IntervalDepth) + depth;
}
else
{
if (varWindowIsNull)
{
panles[i].depth = (panles[i].depth % IntervalDepth) + depth;
continue;
}
panles[i].depth += depth;
}
}
if (effectiveWindow > 1)
{
UIPanel tmp = mMakePanle.GetComponent<UIPanel>();
tmp.depth = depth - 1;
mMakePanle.SetActive(true);
}
else
{
mMakePanle.SetActive(false);
}
}
/// <summary>
/// 获取是否有Dilog窗口打开并且激活
/// </summary>
public bool IsDialogOpen()
{
if (mOpenDialog.Count == 0)
{
return false;
}
foreach (KeyValuePair<string, GameObject> item in mOpenDialog)
{
if (item.Value != null && item.Value.activeSelf)
{
return true;
}
}
return false;
}
private Transform DetachChildren(GameObject obj)
{
Transform varWindow = null;
for (int i = 0; i < obj.transform.childCount; i++)
{
Transform tmp = obj.transform.GetChild(i);
if (tmp.childCount >= 1)
{
varWindow = tmp;
break;
}
}
if (varWindow != null && varWindow.parent != null)
{
varWindow.parent = null;
}
Object.DestroyObject(obj);
return varWindow;
}
/// <summary>
/// 用户协议弹窗
/// </summary>
/// <param name="context"></param>
/// <param name="callback"></param>
public void OpenUserHttpsDialog(string context, ReturnResultCallback callback)
{
DoneLoadDialog doneLoad = (GameObject dialog) =>
{
if (dialog == null)
{
return;
}
Dialog_UserHttps https = dialog.GetComponent<Dialog_UserHttps>();
if (https != null)
{
https.SetContext(context);
https.pCallback = callback;
}
};
OpenDialog(Dialog_UserHttps.DialogPathName, doneLoad);
}
/// <summary>
/// 确定弹窗
/// </summary>
/// <param name="context"></param>
public void OpenSureDialog(string context, ReturnResultCallback callback = null, Dialog_Sure.AtlasSpriteName atlasName = Dialog_Sure.AtlasSpriteName.none)
{
DoneLoadDialog doneLoad = (GameObject dialog) =>
{
if (dialog == null)
{
return;
}
Dialog_Sure sure = dialog.GetComponent<Dialog_Sure>();
if (sure != null)
{
sure.SetContext(context);
sure.pCallback = callback;
if (atlasName != Dialog_Sure.AtlasSpriteName.none)
{
sure.SetTitle(atlasName);
}
}
};
OpenDialog(Dialog_Sure.DialogPathName, doneLoad);
}
/// <summary>
/// 二次确认弹窗
/// </summary>
/// <param name="context"></param>
/// <param name="callback"></param>
public void OpenConfirmationDialog(string context, ReturnResultCallback callback = null, Dialog_Confirmation.AtlasSpriteName atlasName = Dialog_Confirmation.AtlasSpriteName.none)
{
DoneLoadDialog doneLoad = (GameObject dialog) =>
{
if (dialog == null)
{
return;
}
Dialog_Confirmation sure = dialog.GetComponent<Dialog_Confirmation>();
if (sure != null)
{
sure.SetContext(context);
sure.pCallback = callback;
sure.SetTitle(atlasName);
}
};
OpenDialog(Dialog_Confirmation.DialogPathName, doneLoad);
}
/// <summary>
/// 公告
/// </summary>
/// <param name="context"></param>
/// <param name="callback"></param>
public void OpenNoticeDialog(string context, ReturnResultCallback callback = null)
{
DoneLoadDialog doneLoad = (GameObject dialog) =>
{
if (dialog == null)
{
return;
}
Dialog_Notice notice = dialog.GetComponent<Dialog_Notice>();
if (notice != null)
{
notice.SetContext(context);
notice.pCallback = callback;
}
};
OpenDialog(Dialog_Notice.DialogPathName, doneLoad);
}
/// <summary>
/// 公告
/// </summary>
/// <param name="context"></param>
/// <param name="callback"></param>
public void OpenFirstTipDialog(string context, ReturnResultCallback callback = null)
{
DoneLoadDialog doneLoad = (GameObject dialog) =>
{
if (dialog == null)
{
return;
}
Dialog_FirstTip notice = dialog.GetComponent<Dialog_FirstTip>();
if (notice != null)
{
notice.SetContext(context);
notice.pCallback = callback;
}
};
OpenDialog(Dialog_FirstTip.DialogPathName, doneLoad);
}
private void OpenDialog(string pathName, DoneLoadDialog callback)
{
pathName = pathName.ToLower();
if (IsDialogOpen())
{
CloseAllDialog();
}
if (mOpenDialog.ContainsKey(pathName))
{
GameObject obj = mOpenDialog[pathName];
if (obj != null)
{
SetDialogDepth(obj.transform);
obj.SetActive(true);
}
callback(obj);
return;
}
mOpenDialog.Add(pathName, null);
DownloadCallback doneCallback = (string filePath, Object obj) =>
{
if (obj == null)
{
return;
}
GameObject dialog = Object.Instantiate(obj as GameObject);
Transform dialogWindow = DetachChildren(dialog);
if (dialogWindow == null)
{
}
mOpenDialog[pathName] = dialogWindow.gameObject;
dialogWindow.SetParent(mDialogRoot.transform);
dialogWindow.localPosition = Vector3.zero;
dialogWindow.localScale = Vector3.one;
SetDialogDepth(dialogWindow);
if (callback != null)
{
callback(dialogWindow.gameObject);
}
};
ResourcesManager.GetInstance().AddResourceDownload(pathName, doneCallback);
}
private void SetDialogDepth(Transform dialogWindow)
{
if (dialogWindow == null)
{
mMakePanle.SetActive(false);
SetWindowDepth(null);
return;
}
UIPanel[] panels = dialogWindow.GetComponentsInChildren<UIPanel>();
int depth = MaxWindowDepth + 5;
for (int i = 0; i < panels.Length; i++)
{
panels[i].depth += depth;
}
UIPanel makePanle = mMakePanle.GetComponent<UIPanel>();
if (makePanle != null)
{
makePanle.depth = depth - 5;
mMakePanle.SetActive(true);
}
}
public void CloseDialog(string pathName)
{
string name = pathName.ToLower();
if (!mOpenDialog.ContainsKey(name))
{
return;
}
GameObject obj = mOpenDialog[name];
if (obj != null)
{
obj.SetActive(false);
SetDialogDepth(null);
}
}
public void CloseAllDialog()
{
SortedDictionary<string, GameObject>.Enumerator dialogEnum = mOpenDialog.GetEnumerator();
for (int i = 0; i < mOpenDialog.Count; i++)
{
dialogEnum.MoveNext();
GameObject obj = dialogEnum.Current.Value;
if (obj != null)
{
obj.SetActive(false);
}
}
SetDialogDepth(null);
}
/// <summary>
/// 销毁一个窗口
/// </summary>
/// <param name="varPathName"></param>
public void DestroyWindow(string varPathName, bool isOpenMake)
{
varPathName = varPathName.ToLower();
if (mOpenWindow.ContainsKey(varPathName))
{
GameObject obj = mOpenWindow[varPathName];
if (obj != null)
{
Object.Destroy(obj);
}
mOpenWindow.Remove(varPathName);
mOpenWindowKey.Remove(varPathName);
SetWindowDepth(null);
}
}
public void DestroyWindow(string varPathName)
{
DestroyWindow(varPathName, false);
}
public void DestroyWindowAll()
{
SortedDictionary<string, GameObject>.Enumerator windowEnum = mOpenWindow.GetEnumerator();
for (int i = 0; i < mOpenWindow.Count; i++)
{
windowEnum.MoveNext();
GameObject obj = windowEnum.Current.Value;
if (obj != null)
{
Object.Destroy(obj);
}
}
mOpenWindow.Clear();
mOpenWindowKey.Clear();
SetWindowDepth(null);
}
public void DestroyWindowByObj(GameObject target)
{
SortedDictionary<string, GameObject>.Enumerator windowEnum = mOpenWindow.GetEnumerator();
for (int i = 0; i < mOpenWindow.Count; i++)
{
windowEnum.MoveNext();
GameObject obj = windowEnum.Current.Value;
if (obj == target)
{
Object.Destroy(target);
mOpenWindow.Remove(windowEnum.Current.Key);
mOpenWindowKey.Remove(windowEnum.Current.Key);
}
}
SetWindowDepth(null);
}
/// <summary>
/// 判断窗口是否被打开状态
/// </summary>
/// <param name="pathName"></param>
public bool WindowIsActive(string pathName)
{
string key = pathName.ToLower();
if (mOpenWindow.ContainsKey(key))
{
GameObject obj = null;
if (mOpenWindow.TryGetValue(key , out obj))
{
if (obj != null && obj.activeInHierarchy)
{
return true;
}
}
}
return false;
}
/// <summary>
/// 删除除自己之外的窗口
/// </summary>
/// <param name="target"></param>
public void DestroyWindowAllExceptObj(string pathName)
{
string key = pathName.ToLower();
GameObject target = null;
if (mOpenWindow.ContainsKey(key))
{
target = mOpenWindow[key];
}
if (key != string.Empty && target != null)
{
mOpenWindow.Remove(key);
SortedDictionary<string, GameObject>.Enumerator windowEnum = mOpenWindow.GetEnumerator();
for (int i = 0; i < mOpenWindow.Count; i++)
{
windowEnum.MoveNext();
GameObject obj = windowEnum.Current.Value;
if (obj != null)
{
Object.Destroy(obj);
}
}
mOpenWindow.Clear();
mOpenWindowKey.Clear();
mOpenWindow.Add(key, target);
mOpenWindowKey.Add(key);
}
SetWindowDepth(null);
}
/// <summary>
/// 更改窗口状态
/// </summary>
/// <param name="varPathName"></param>
/// <param name="varState"></param>
public void SetWindowState(string varPathName, bool varState)
{
if (!mOpenWindow.ContainsKey(varPathName))
{
return;
}
mOpenWindow[varPathName].SetActive(varState);
}
}
//一个使用示例
public class Dialog_Confirmation : MonoBehaviour
{
public enum AtlasSpriteName
{
none,
atlas_gonggao,
atlas_jiesanfangjian,
atlas_fanhuidating,
atlas_gengxintishi
}
public static string DialogPathName
{
get
{
return "ui/ui_dialog/twoconfirmation";
}
}
private ReturnResultCallback mCallback;
public ReturnResultCallback pCallback
{
set
{
mCallback = value;
}
}
Transform mTranform;
void Awake()
{
mTranform = transform;
GameTools.RegisterButton(mTranform, "Button/sure", OnSure);
GameTools.RegisterButton(mTranform, "Button/cancle", OnCancle);
}
public void SetContext(string text)
{
GameTools.SetLabelText(mTranform, "context", text);
}
private void OnCancle(GameObject go)
{
if (mCallback != null)
{
mCallback(ResultDialog.No);
}
WindowManager.GetInstance().CloseDialog(DialogPathName);
}
private void OnSure(GameObject go)
{
if (mCallback != null)
{
mCallback(ResultDialog.Yes);
}
WindowManager.GetInstance().CloseDialog(DialogPathName);
}
public void SetTitle(AtlasSpriteName spriteName)
{
UISprite sprite = GameTools.GetComponent<UISprite>(mTranform, "Bg/Title");
if (spriteName== AtlasSpriteName.none)
{
sprite.gameObject.SetActive(false);
return;
}
if (sprite != null)
{
sprite.spriteName = spriteName.ToString();
sprite.MakePixelPerfect();
}
sprite.gameObject.SetActive(true);
}
}