Unity3D – 简单的UI管理结构
使用Unity3D做一些小游戏原型的时候,虽然我们想做UI,但是又没有美术的支持,我们使用一个简单的UI模板,所有不需要做UI的小游戏直接使用就行了,也不必要每次都要自己写。
首先写一个UIBase类,所有的UI类都继承这个类就可以了 。
代码块
UIBase类
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using DG.Tweening;
/// <summary>
/// UI控制器基类
/// </summary>
public abstract class UIBase : MonoBehaviour
{
private Transform m_Transform;
//UI是否已经显示
[HideInInspector]
public bool m_SelfShowed = false;
// UI是否被初始化
private bool m_Inited = false;
private Vector3 m_DefaultPos = Vector3.zero;
private CanvasGroup m_CanvasGroup;
void Awake()
{
m_Transform = transform;
m_DefaultPos = m_Transform.position;
}
void Start () {
InitSuper ();
}
public void InitSuper()
{
if (m_Inited)
return;
m_Inited = true;
m_CanvasGroup = GetComponent<CanvasGroup> ();
if(m_CanvasGroup == null){
gameObject.AddComponent<CanvasGroup> ();
m_CanvasGroup = GetComponent<CanvasGroup> ();
m_CanvasGroup.alpha = 1;
m_CanvasGroup.ignoreParentGroups = false;
m_CanvasGroup.interactable = false;
m_CanvasGroup.blocksRaycasts = false;
}
gameObject.SetActive (true);
Button[] buttons = GetComponentsInChildren<Button> ();
foreach (var item in buttons) {
Button btn = item as Button;
btn.onClick.AddListener (delegate {
this.DidOnClick (btn.gameObject);
});
}
DidInitUI ();
}
public void ShowUI()
{
if (!m_SelfShowed) {
InitSuper ();
DidShowUI ();
}
}
public void HideUI()
{
if (m_SelfShowed) {
InitSuper ();
DidHideUI ();
}
}
public void OpenActivity()
{
m_SelfShowed = true;
gameObject.SetActive (true);
m_Transform.position = m_DefaultPos + new Vector3 (Screen.width, 0, 0);
m_Transform.DOMoveX (m_DefaultPos.x, 0.2f);
}
public void CloseActivity ()
{
m_SelfShowed = false;
float outPos = m_Transform.position.x - Screen.width;
m_Transform.DOMoveX (outPos, 0.2f).OnComplete (delegate {
gameObject.SetActive(false);
});
}
/// <summary>
/// 在Start中初始化UI的操作
/// </summary>
public abstract void DidInitUI ();
/// <summary>
/// 执行显示UI的操作
/// </summary>
public abstract void DidShowUI ();
/// <summary>
/// 执行关闭UI的操作
/// </summary>
public abstract void DidHideUI ();
/// <summary>
/// 注册按钮点击事件
/// </summary>
/// <param name="sender">Sender.</param>
public abstract void DidOnClick (GameObject sender);
}
所有继承UIBase的类只需要实现几个抽象方法就可以了,ShowUI和HideUI的具体实现都放到了DidShowUI()和DidHideUI()里面,基类还用了DoTween来实现一个简单的打开UI,关闭UI的动画。
假如我们要做一个只有一个开始游戏按钮的主界面
新建一个类:MenuUI实现如下:
代码块
UIBase类
using UnityEngine;
using System.Collections;
public class MenuUI : UIBase {
public override void DidInitUI (){ }
public override void DidShowUI ()
{
OpenActivity ();
}
public override void DidHideUI ()
{
CloseActivity ();
}
public override void DidOnClick (GameObject sender)
{
switch (sender.name) {
case "ButtonStart":
GameManager.Instance.GameStart ();
break;
default:
break;
}
}
}
点击按钮开始游戏。
其他相应的UI也可以使用这种方法。
下面是UI管理类,让你建立简单的UI不需要做任何操作就可以运行游戏了。
新建一个叫UIManager的类
实现如下:
代码块
using UnityEngine;
using System.Collections;
using MicroGame;
using System.Collections.Generic;
public class UIManager : Singleton<UIManager> {
/// <summary>
/// UI信息
/// </summary>
[System.Serializable]
public struct UIInfo
{
public UIType type;
public UIBase ui;
}
/// <summary>
/// UI类型
/// </summary>
public enum UIType
{
_NONE,
_MENU, // 进入游戏主界面
_GAMEOVER, // 游戏结束界面
_INGAME, // 答题界面
_CHOOSELEVEL // 选关界面
}
// 所有UI信息
[SerializeField]
private UIInfo[] m_UIInfo;
// 保存已经显示的UI
[SerializeField]
private Stack<UIBase> m_UIStack;
// 当前UI类型
private UIType m_CurrentType = UIType._NONE;
// 即将打开UI的类型
private UIType m_NextType = UIType._NONE;
void Start () {
InitUI ();
}
#region private funcs
// 初始化所有UI
void InitUI()
{
foreach (var item in m_UIInfo) {
if (item.type == UIType._MENU) {
ShowUI (item.type);
} else {
item.ui.gameObject.SetActive (false);
}
}
}
// 根据UI类型获取UI实例
UIBase GetUI(UIType type)
{
foreach (var item in m_UIInfo) {
if (item.type == type)
return item.ui;
}
return null;
}
// 根据UI实例获取UI类型
UIType GetType(UIBase ui)
{
foreach (var item in m_UIInfo) {
if (item.ui == ui)
return item.type;
}
return UIType._NONE;
}
#endregion
#region public funcs
public void ShowUI(UIType type)
{
if (type == m_CurrentType) {
return;
}
if (m_CurrentType != UIType._NONE) {
GetUI (m_CurrentType).HideUI ();
}
if (type != UIType._NONE && m_NextType == UIType._NONE) {
m_NextType = type;
GetUI (m_NextType).ShowUI ();
}
m_CurrentType = m_NextType;
m_NextType = UIType._NONE;
}
public void HideUI(UIType type){ }
#endregion
}
要打开某个UI只需要调用一下UIManager.Instance.ShowUI (UIType._GAMEOVER);
就可以了。这样是不是很方便呢。
–Rocky