using UnityEngine;
using System;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.EventSystems;
public class UIManager : MonoBehaviour {
private static UIManager _Instance;
public static UIManager GetInstance()
{
if (_Instance == null) { InitRoot(); }
return _Instance;
}
private Dictionary<string, string> _allUINameAndPath; //key:UI名称,value:UI的预制体的加载路径。初始化的时候填写
private Dictionary<string, UITypeBase> _allUI; //key:UI名称,UI对象。使用的时候动态添加
private List<string> _simpleUIStack; //保存通过按钮等弹出的界面的集合,不包含初始化后就固定显示不动的UI。
void Awake()
{
_Instance = this;
InitAllUINameAndPath();
}
/// <summary>
/// 创建Canvas,SystemEvent,UICamera,注意方法里面摄像机的分辨率写的是800,600
/// </summary>
static void InitRoot()
{
//创建一个物体来挂在此TTUIRoot组件
GameObject go = new GameObject("Canvas");
go.layer = LayerMask.NameToLayer("UI");
_Instance = go.AddComponent<UIManager>();
go.AddComponent<RectTransform>();
//创建Canvas
Canvas can = go.AddComponent<Canvas>();
can.renderMode = RenderMode.ScreenSpaceCamera;
can.pixelPerfect = true;
//添加这个组件,一般创建Canvas的几件套
go.AddComponent<GraphicRaycaster>();
//给此脚本的root变量设置为本身
//创建UI摄像机,后面的都是一些设置参数
GameObject camObj = new GameObject("UICamera");
camObj.layer = LayerMask.NameToLayer("UI");
camObj.transform.parent = go.transform;
camObj.transform.localPosition = new Vector3(0, 0, -100f);
Camera cam = camObj.AddComponent<Camera>();
cam.clearFlags = CameraClearFlags.Depth;
cam.orthographic = true;
cam.farClipPlane = 200f;
can.worldCamera = cam;
cam.cullingMask = 1 << 5;
cam.nearClipPlane = -50f;
cam.farClipPlane = 50f;
//添加监听,和GUILayer组件
//camObj.AddComponent<AudioListener>();
camObj.AddComponent<GUILayer>();
//这个也是Canvas的几件套之一,按照平时创建的一一填写即可
CanvasScaler cs = go.AddComponent<CanvasScaler>();
cs.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
cs.referenceResolution = new Vector2(800, 600f);
cs.screenMatchMode = CanvasScaler.ScreenMatchMode.Expand;
//add Event System
GameObject esObj = GameObject.Find("EventSystem");
if (esObj != null)
{
GameObject.DestroyImmediate(esObj);
}
GameObject eventObj = new GameObject("EventSystem");
eventObj.layer = LayerMask.NameToLayer("UI");
eventObj.transform.SetParent(go.transform);
eventObj.AddComponent<EventSystem>();
eventObj.AddComponent<UnityEngine.EventSystems.StandaloneInputModule>();
}
/// <summary>
/// 初始化存放 UI名称,UI路径 的字典_allUINameAndPath,或者读josn来存储
/// </summary>
void InitAllUINameAndPath()
{
_allUINameAndPath = new Dictionary<string, string>();
_allUINameAndPath.Add(GlobeParameter.UIName_MenuButton,GlobeParameter.UIPath_MenuButton);
_allUINameAndPath.Add(GlobeParameter.UIName_MenuPanel, GlobeParameter.UIPath_MenuPanel);
_allUINameAndPath.Add(GlobeParameter.UIName_OpertionButton, GlobeParameter.UIPath_OpertionButton);
_allUINameAndPath.Add(GlobeParameter.UIName_GameOverPanel, GlobeParameter.UIPath_GameOverPanel);
_allUINameAndPath.Add(GlobeParameter.UIName_FoodFullImage, GlobeParameter.UIPath_FoodFullImage);
_allUINameAndPath.Add(GlobeParameter.UIName_DangerCountDown, GlobeParameter.UIPath_DangerCountDown);
}
/// <summary>
/// 显示UI
/// </summary>
/// <param name="uiName"> UI名称</param>
public void ShowUI(string uiName)
{
if (string.IsNullOrEmpty(uiName) || _allUINameAndPath.ContainsKey(uiName) == false)
{
return;
}
UITypeBase uiTypeBase = null;
if (_allUI == null)
{
_allUI = new Dictionary<string, UITypeBase>();
}
if (_simpleUIStack == null)
{
_simpleUIStack = new List<string>();
}
if (_allUI.ContainsKey(uiName))
{
uiTypeBase = _allUI[uiName];
//打开的情况下,再次点击就关闭UI
if (uiTypeBase._isActive == true && _allUI[uiName].UIShowMode != UIShowMode.ShowTimeLimit)
{
Hide(uiName);
return;
}
}
else if (_allUI.ContainsKey(uiName) == false)
{
uiTypeBase = InstantiateUIPrefab(uiName);
}
switch (uiTypeBase.UIShowMode)
{
case UIShowMode.Fixed:
break;
case UIShowMode.Noraml:
_simpleUIStack.Add(uiName);
break;
case UIShowMode.HideOther:
HideOther(uiName);
_simpleUIStack.Add(uiName);
break;
case UIShowMode.ShowTimeLimit:
if (_simpleUIStack.Contains(uiName))
{
StopCoroutine("HideDelay");
}
else
{
_simpleUIStack.Add(uiName);
}
//ChangeUIPosition(uiName);
StartCoroutine("HideDelay", uiName);
break;
}
Active(uiName);
}
/// <summary>
/// 显示UI: 物体挂载脚本里的数据,传递到UI界面更新数据用。
/// </summary>
/// <param name="uiName"> UI的名字</param>
/// <param name="g"> 挂载数据脚本的物体</param>
public void ShowUI(string uiName, GameObject g)
{
ShowUI(uiName);
Active(uiName, g);
}
/// <summary>
/// 改变UI的位置,预制体的UI是在原点,改变成鼠标的点击位置。
/// </summary>
/// <param name="uiName"></param>
public void ChangeUIPosition(string uiName)
{
Vector2 _pos = Vector2.one;
RectTransformUtility.ScreenPointToLocalPointInRectangle(gameObject.GetComponent<Canvas>().transform as RectTransform,
Input.mousePosition, gameObject.GetComponent<Canvas>().worldCamera, out _pos);
_allUI[uiName].GetComponent<RectTransform>().anchoredPosition = _pos;
}
/// <summary>
/// 延迟隐藏UI
/// </summary>
/// <param name="uiName"> UI名称</param>
/// <param name="time"> 延迟时间</param>
/// <returns></returns>
IEnumerator HideDelay(string uiName)
{
yield return new WaitForSeconds(3f);
Hide(uiName);
}
/// <summary>
/// 隐藏UI
/// </summary>
/// <param name="uiName"></param>
public void Hide(string uiName)
{
UITypeBase uiTypeBase = _allUI[uiName];
if (uiTypeBase._isActive == true)
{
uiTypeBase.Hide();
_simpleUIStack.Remove(uiName);
}
}
/// <summary>
/// 除了参数以外的所有能隐藏的UI(Fixed类型的UI是不能隐藏),都隐藏
/// </summary>
/// <param name="uiName"></param>
public void HideOther(string uiName)
{
if (_simpleUIStack != null)
{
foreach (string s in _simpleUIStack)
{
if (s != uiName || _allUI[uiName].UIShowMode == UIShowMode.ShowTimeLimit)
{
_allUI[s].Hide();
}
}
//清空栈
_simpleUIStack.Clear();
}
}
public void Reflush(string uiName)
{
_allUI[uiName].Active();
}
public void Reflush(string uiName,GameObject g)
{
_allUI[uiName].Active(g);
}
public void ReflushAsync(string uiName, GameObject g)
{
_allUI[uiName].RefreshAsync(g);
}
/// <summary>
/// 异步刷新UI
/// </summary>
/// <param name="uiName"></param>
/// <summary>
/// 激活UI
/// </summary>
/// <param name="name">UI名称</param>
void Active(string name)
{
_allUI[name].Active();
}
void Active(string name, GameObject g)
{
_allUI[name].Active(g);
}
/// <summary>
/// 根据名称实例化UI
/// </summary>
/// <param name="name"></param>
UITypeBase InstantiateUIPrefab(string name)
{
string path = _allUINameAndPath[name];
GameObject g = GameObject.Instantiate(Resources.Load(path)) as GameObject;
g.name = name;
g.transform.SetParent(gameObject.transform, false);
if (g.GetComponent<UITypeBase>() == false)
{
Debug.LogError("物体" + g.name + "没有挂载相关脚本");
return null;
}
UITypeBase uiTypeBase = g.GetComponent<UITypeBase>();
_allUI.Add(name,uiTypeBase);
return uiTypeBase;
}
}
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
/*
* 所有UI都继承自UITypeBase
* 如有特殊需要就重写生命周期方法如Reflush(),Active(),Hide()
* 所有UI都要选择自己的UIShowMode,
* Fixed:可用于固定的窗口,如主界面,
* Noraml:可用于普通的可以共同显示的UI
* HideOther:只能独立显示在屏幕的,其中不包含Fixed类型的UI
*/
public abstract class UITypeBase : MonoBehaviour
{
public UIShowMode UIShowMode;
public bool _isActive = false;
#region virtual method
/// <summary>
/// 激活
/// </summary>
public virtual void Active()
{
_isActive = true;
this.gameObject.SetActive(true);
Refresh();
}
/// <summary>
/// 更新UI数据
/// </summary>
public virtual void Refresh()
{
}
public virtual void Active(GameObject g)
{
_isActive = true;
this.gameObject.SetActive(true);
Refresh(g);
}
public virtual void Refresh(GameObject g)
{
}
public virtual void RefreshAsync(GameObject g)
{
}
/// <summary>
/// 隐藏
/// </summary>
public virtual void Hide()
{
_isActive = false;
this.gameObject.SetActive(false);
}
#endregion
}
public enum UIShowMode
{
Fixed, //固定窗口
Noraml, //普通窗口
HideOther, //隐藏其他窗口
ShowTimeLimit, //显示限制时间,仅显示若干秒关闭,或者点击其他就关闭这个模式的UI
}