引子
界面管理是做什么用的?为了回答这个问题让我们先来罗列与界面操作相关的代码:
- 在网络消息的回掉函数中我们发现了对界面的显示、隐藏及遮挡关系调整的操作。
public static void OnPacket_UserLogon(object pack)
{
... ...
Debug.Log("Logon Succeed");
Gamedata.me.userinfo = userLogon.UserInfo;
PanelManager.me.HideAll(); // 界面的隐藏
PanelManager.me.Get((int)PanelId.PanelMain).Show(); // 界面的显示
PanelManager.me.Get((int)PanelId.PanelMain).ToTop(); // 调整界面到最前方
... ...
}
- 在界面的初始化函数中我们发现了获取界面控件的操作
public class PanelLogon : PanelBase
{
InputField username; // 用户名
InputField password; // 密码
public override void Init()
{
... ...
username = controls.GetInputField("InputFieldUsername");
password = controls.GetInputField("InputFieldPassword");
... ...
}
}
- 在游戏初始化阶段,我们发现了为向PanelManager中注册Prfab的操作。
PanelManager.me.RegistPrefab((int)PanelId.PanelLogon, AssetManager.me.GetPanel("PanelLogon"));
PanelManager.me.RegistPrefab((int)PanelId.PanelMain, AssetManager.me.GetPanel("PanelMain"));
- 在某界面中我们发现了事件处理函数。
void ProcessProgress(EventProgress evt)
{
int intProgress = (int)(evt.progress * 100);
txProcess.text = intProgress.ToString();
}
整理以上罗列出的代码,给出本文的界面管理的内容:
- 界面的显示、隐藏、遮挡关系。
- 界面的加载与卸载。
- 界面控件的获得。
- 界面中的事件响应。
- 除以上在代码中罗列的内容外,本文还加入了部分界面管理与热跟新融合的部分内容。
本文的思路: 整理分析常见的界面管理的数据结构和遮挡关系管理方法,并给出本文采用的遮挡关系。整理分析常见的控件获得方式,给出本文采用的控件获取方式。讲解PanelBase和PanelManager中的主要函数来理解界面的显示、隐藏、加载及卸载的实现。界面中全局事件的相应会放到事件系统中讲解,最后附录中给出本文的完整的源代码。
界面管理的数据结构和遮挡关系的管理方法
界面管理的数据结构一般有两中:栈结构和对结构。
* 栈结构为基础的界面管理。
在这种方式中界面的显示相当与如栈,而界面的隐藏则相当于出栈。这种方式的好处是结构清晰、遮挡关系的管理简单并天生就有界面显示流的逆向追踪能力。当显示一个界面时,将这个界面放入栈顶并显示,处于栈顶的界面永远处于遮挡关系的最前方。当隐藏一个界面是将从这个界面到栈顶的界面一律出栈并隐藏。这种方式的不足是经常不能满足策划对界管理的要求,于是加入各种补丁使得原本清晰简单的结构变的复杂而混乱。
* 以堆结构为基础的界面管理。
这种方式在实现遮挡关系管理上要比栈结构复杂,要实现诸如ToTop、ToBottom、MoveForward、MoveBackward、SetQueueIndex等控制遮挡关系的函数。
本文实现的是阉割版的堆结构为基础的界面管理,即仅实现了众多遮挡控制函数中的ToTop,在使用上显示即ToTop。另外,有些复杂的界面管理还实现了界面显示流的逆向追踪,这个也不在本文的讨论范围。
界面中控件的取得
常见的控件获取的三种方式
* 拖拽式。 这种方式大概是这样实现的, 首先在代码中声明控件变量,在制作Panel的prefab时将相应的控件拖拽到prefab上。 代码中大概是这样的:
class PanelHero : Behaviour
{
public Button btnUpLevel;
public Button btnUpStar;
public void Awake()
{
btnUpLevel.onClick.AddListener(OnUpLevelClick);
btnUpStar.OnClick.AddListener(OnUpStarClick);
}
... ...
}
- 路径查找式。这中方式与第一中方式类似, 但在制作界面的Prefab时不需要将控件拖拽到相应的变量上,在加载界面是由程序通过路径查找的方式找到相应的空间, 代码大概是这样的。
class PanelHero : Behaviour
{
public Button btnUpLevel;
public Button btnUpStar;
public void Awake()
{
btnUpLevel = transform.Find("HeroLevel/ButtonUpLevel").GetComponent<Button>();
btnUpStar = trnaform.Find("HeroQualityAndStar/ButtonUpStar").GetComponent<Button>();
btnUpLevel.onClick.AddListener(OnUpLevelClick);
btnUpStar.OnClick.AddListener(OnUpStarClick);
}
... ...
}
- 注册式。 这种方式需要两个类, Register和Container, 在制作控件时将Container置于Panel上, 将Register置于要与程序产生关联的控件上, 在程序中使用使用首先得到Container,然后在Container中取得相应的控件。 代码如下
// 控件注册器
class UiControlRegistor : MonoBehaviour
{
// 指定的目标容器
public UiControlContainer PointedContainer = null;
public virtual void Awake()
{
container.RegistObject(name, gameObject); // 注册本控件
}
// 得到控件的目标容器
public UiControlContainer container
{
// 如果制定了目标容器就返回制定的目标容器,
// 否则依次向跟节点查找容器, 返回路径上的第一个容器作为目标容器
get { return PointedContainer ? PointedContainer :
transform.GetComponentInParent<UiControlContainer>(); }
}
}
// 控件容器
class UiControlContainer : MonoBehaviour
{
// GameObject 类型的容器
Dictionary<string, GameObject> objects = new Dictionary<string, GameObject>();
// 泛型的控件注册函数
bool RegistT<T>(Dictionary<string, T> datas, string name, T unit)
{
if (datas.ContainsKey(name))
{
Debug.LogError("name(" + name + ") already exist");
return false;
}
datas.Add(name, unit);
return true;
}
// GameObject类型的控件注册函数
public bool RegistObject(string name, GameObject obj)
{
return RegistT(objects, name, obj);
}
... ...
}
下面给出这三种方案的对比:
第一种方案(拖拽式)的优点, 简洁,直观,效率高。缺点prefab与对应的脚本关联行强,难于分离脚本开发与perfab制作,很难支持lua热更新。
第二种方案(路径查找式)的优点,简洁,直观, prefab的制作不再依赖与脚本开发。缺点查找的效率低,脚本开发依旧依赖与prefab制作。这种方案可以将prefab的制作人员与脚本开发人员分离,但每次修改prefab后脚本依旧要紧随其后的修改。这种方案可以支持Lua热跟新。
第三种方案(注册式)优点prefab的制作与脚本开发很好的分离,很好的支持lua热跟新。效率介于前两种方案之间,缺点是结构稍显复杂。本文采用的方案是第三种方案。
PanelBase的主要函数
PanelBase是界面的基类, 主要的接口有Init,Show, Hide, Refresh,与层次相关的接口前面已经提到过了,本文采用的是阉割版,因此在这个类中看不到遮挡关系系列的函数。对于界面控件的响应函数应该放到具体的Panel里,对于全局事件的相应放到事件系统中讲解。
/// <summary>
/// 界面的基类
/// 定义了诸如Init、Show、Hide、Refresh等可重写的流程函数
/// </summary>
[RequireComponent(typeof(UiControlContainer))]
public class PanelBase : MonoBehaviour
{
/// <summary>
/// 控件容器
/// </summary>
public UiControlContainer controls { get { return GetComponent<UiControlContainer>(); } }
/// <summary>
/// 所有SubPanel
/// </summary>
public PanelBase[] subPanels { get { return controls.panelbases.Values.ToArray<PanelBase>(); } }
/// <summary>
/// 根据名字获取Button控件
/// </summary>
/// <param name="name">Button的名字</param>
/// <returns>Button控件</returns>
public virtual void Init()
{
foreach (PanelBase subPanel in subPanels)
{
bool active = gameObject.activeSelf;
gameObject.SetActive(true);
foreach (PanelBase subPanel in subPanels)
{
subPanel.Init();
}
gameObject.SetActive(active);
}
}
/// <summary>
/// 显示界面
/// </summary>
public virtual void Show()
{
gameObject.SetActive(true);
}
/// <summary>
/// 隐藏界面
/// </summary>
public virtual void Hide()
{
gameObject.SetActive(false);
}
/// <summary>
/// 刷新界面
/// </summary>
public virtual void Refresh()
{
}
}
PanelManager的主要函数
PanelManager是界面管理的核心类, 主要函数有RegistPrefab、Get、HideAll、RefreshAll等
public class PanelManager : Singleton<PanelManager>
{
// 界面的实例化函数
public delegate PanelBase FuncInstanceUiBase(PanelBase prefab);
public FuncInstanceUiBase InstanceUiBase;
// prefab 容器
private readonly Dictionary<int, PanelBase> prefabs = new Dictionary<int, PanelBase>();
// 已经加载的界面容器
private readonly Dictionary<int, PanelBase> uis = new Dictionary<int, PanelBase>();
/// <summary>
/// 注册界面的Prefab
/// </summary>
/// <param name="uiid">界面的类型id</param>
/// <param name="prefab">界面的prefab</param>
public void RegistPrefab(int uiid, PanelBase prefab)
{
prefabs.Add(uiid, prefab);
}
/// <summary>
/// 获取界面
/// </summary>
/// <param name="uiid">界面的类型id</param>
/// <returns></returns>
public PanelBase Get(int uiid)
{
if (uis.ContainsKey(uiid))
return uis[uiid];
if (prefabs.ContainsKey(uiid))
{
var ui = InstanceUiBase(prefabs[uiid]);
uis.Add(uiid, ui);
ui.gameObject.SetActive(true);
ui.name = ui.name.Substring(0, ui.name.IndexOf("(Clone)"));
ToTop(ui);
ui.Init();
AdjustPanelPosition(ui);
}
return null;
}
/// <summary>
/// 隐藏所有界面
/// </summary>
public void HideAll()
{
foreach (var ui in uis.Values)
ui.Hide();
}
/// <summary>
/// 显示所有界面
/// </summary>
public void RefreshAll()
{
foreach (var ui in uis.Values)
ui.Refresh();
}
}
小结
本文从常见的界面相关的源代码出发,提出了界面管理的基础功能,并重点讲解了界面控件的获得和界面管理的数据结构。有关界面管理的高级部分,例如界面的过度动画,界面切换触发的功能(例如新手引导),界面的导航与追踪等部分将在下一篇界面管理的文章中给出。
附:完整源代码
// PanelBase.cs
// Author: Iann
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using System.Reflection;
namespace Assets.Script.Frame
{
/// <summary>
/// 界面的基类
/// 定义了诸如Init、Show、Hide、Refresh等可重写的流程函数
/// </summary>
[RequireComponent(typeof(UiControlContainer))]
public class PanelBase : MonoBehaviour
{
/// <summary>
/// 控件容器
/// </summary>
public UiControlContainer controls { get { return GetComponent<UiControlContainer>(); } }
/// <summary>
/// 所有SubPanel
/// </summary>
public PanelBase[] subPanels { get { return controls.panelbases.Values.ToArray<PanelBase>(); } }
/// <summary>
/// 根据名字获取Button控件
/// </summary>
/// <param name="name">Button的名字</param>
/// <returns>Button控件</returns>
public virtual Button GetButton(string name)
{
return controls.GetButton(name);
}
/// <summary>
/// 根据名字获取Button控件
/// </summary>
/// <param name="name">Button的名字</param>
/// <returns>Button控件</returns>
public virtual Text GetText(string name)
{
return controls.GetText(name);
}
/// <summary>
/// 根据名字获取Image控件
/// </summary>
/// <param name="name">Image的名字</param>
/// <returns>Image控件</returns>
public virtual Image GetImage(string name)
{
return controls.GetImage(name);
}
/// <summary>
/// 根据名字获取SubPanel控件
/// </summary>
/// <param name="name">SubPanel的名字</param>
/// <returns>SubPanel控件</returns>
public virtual PanelBase GetSubPanel(string name)
{
return controls.GetPanelBase(name);
}
/// <summary>
/// 界面的初始化函数
/// 一般重载这个函数的主要目的是初始化界面控件
/// 注意控件的注册是在Awake函数中进行的,保证在调用container.get的时候控件注册器的Awake已经调用
/// </summary>
public virtual void Init()
{
#if USE_LOG && LOG_FRAME_UI
Debug.Log("Init Panel " + name + ".");
#endif
bool active = gameObject.activeSelf;
gameObject.SetActive(true); // 确保初始化前UiControlRegister的Awake已经调用
foreach (PanelBase subPanel in subPanels)
{
subPanel.Init();
}
gameObject.SetActive(active);
}
/// <summary>
/// 显示界面
/// </summary>
public virtual void Show()
{
#if USE_LOG && LOG_FRAME_UI
Debug.Log("PaneBase(" + name + ").Show");
#endif
gameObject.SetActive(true);
//OnShow();
Refresh();
}
/// <summary>
/// 隐藏界面
/// </summary>
public virtual void Hide()
{
#if USE_LOG && LOG_FRAME_UI
Debug.Log("PaneBase(" + name + ").Hide");
#endif
gameObject.SetActive(false);
}
/// <summary>
/// 刷新界面
/// </summary>
public virtual void Refresh()
{
#if USE_LOG && LOG_FRAME_UI
Debug.Log("PanelBase(" + name + ").Refresh");
#endif
}
}
}
// PanelManager.cs
// Author: Iann
using System.Collections.Generic;
using UnityEngine;
namespace Assets.Script.Frame
{
/// <summary>
/// 界面管理类
/// 本类提供了界面的加载,显示,隐藏,(关闭)功能
/// 动画过度暂未实现
/// 导航功能暂未实现
/// </summary>
public class PanelManager : Singleton<PanelManager>
{
// 界面的实例化函数
public delegate PanelBase FuncInstanceUiBase(PanelBase prefab);
public FuncInstanceUiBase InstanceUiBase;
// prefab 容器
private readonly Dictionary<int, PanelBase> prefabs = new Dictionary<int, PanelBase>();
// 已经加载的界面容器
private readonly Dictionary<int, PanelBase> uis = new Dictionary<int, PanelBase>();
public void Regist(int uiid, PanelBase ui)
{
//types.Add(typeof(T), uiid);
uis.Add(uiid, ui);
}
/// <summary>
/// 注册界面的Prefab
/// </summary>
/// <param name="uiid">界面的类型id</param>
/// <param name="prefab">界面的prefab</param>
public void RegistPrefab(int uiid, PanelBase prefab)
{
if (prefab == null)
{
Debug.LogError(string.Format("PanelManager.RegistPrefab({0},{1}) Failed !!!",
uiid, prefab));
return;
}
#if USE_LOG
Debug.Log(string.Format("PanelManager.RegistPrefab({0},{1}", uiid, prefab));
#endif
prefabs.Add(uiid, prefab);
}
/// <summary>
/// 获取界面
/// </summary>
/// <param name="uiid">界面的类型id</param>
/// <returns></returns>
public PanelBase Get(int uiid)
{
//如果界面已经加载过, 返回已经加载过的界面
if (uis.ContainsKey(uiid))
return uis[uiid];
// 加载界面
if (prefabs.ContainsKey(uiid))
{
if (prefabs[uiid] == null)
{
Debug.LogError((PanelId)uiid);
}
var ui = InstanceUiBase(prefabs[uiid]);
uis.Add(uiid, ui);
ui.gameObject.SetActive(true); // 确保初始化前UiControlRegister的Awake已经调用
ui.name = ui.name.Substring(0, ui.name.IndexOf("(Clone)"));
ToTop(ui);
ui.Init();
AdjustPanelPosition(ui);
return ui;
}
return null;
}
/// <summary>
/// 调整Panel的位置布局
/// </summary>
/// <param name="ui">待调整的Panel</param>
void AdjustPanelPosition(PanelBase ui)
{
ui.GetComponent<RectTransform>().SetParent(GameObject.Find("Canvas").transform);
var rt = ui.GetComponent<RectTransform>();
var op = ui.GetComponent<RectTransformAdjustor>();
if (op != null)
{
op.Adjust();
}
else
{
ui.transform.localPosition = Vector3.zero;
ui.transform.localScale = Vector3.one;
}
}
/// <summary>
/// 将Panel放到最前面
/// </summary>
/// <param name="ui">待调整的Panel</param>
void ToTop(PanelBase ui)
{
ui.transform.SetAsLastSibling();
}
/// <summary>
/// 隐藏所有界面
/// </summary>
public void HideAll()
{
foreach (var ui in uis.Values)
ui.Hide();
}
/// <summary>
/// 显示所有界面
/// </summary>
public void RefreshAll()
{
foreach (var ui in uis.Values)
ui.Refresh();
}
}
}
// UiControlContainer.cs
// Author: Iann
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
namespace Assets.Script.Frame
{
public class UiControlContainer : MonoBehaviour
{
private readonly Dictionary<string, Button> buttons = new Dictionary<string, Button>();
private readonly Dictionary<string, Image> images = new Dictionary<string, Image>();
private readonly Dictionary<string, InputField> inputs = new Dictionary<string, InputField>();
private readonly Dictionary<string, Text> texts = new Dictionary<string, Text>();
private readonly Dictionary<string, Slider> sliders = new Dictionary<string, Slider>();
private readonly Dictionary<string, GameObject> objects = new Dictionary<string, GameObject>();
public Dictionary<string, PanelBase> panelbases = new Dictionary<string, PanelBase>();
private bool RegistT<T>(Dictionary<string, T> datas, string name, T unit)
{
if (datas.ContainsKey(name))
{
Debug.LogError("name(" + name + ") already exist");
return false;
}
datas.Add(name, unit);
return true;
}
private bool UnRegistT<T>(Dictionary<string, T> datas, string name)
{
if (!datas.ContainsKey(name))
{
Debug.LogError("name not exist");
return false;
}
datas.Remove(name);
return true;
}
// Object
public bool RegistObject(string name, GameObject obj)
{
return RegistT(objects, name, obj);
}
public bool UnRegistObject(string name)
{
return UnRegistT(objects, name);
}
public GameObject GetObject(string name)
{
if (objects.ContainsKey(name))
return objects[name];
return null;
}
// Button
public bool RegistButton(string name, Button button)
{
return RegistT(buttons, name, button);
}
public bool UnRegistButton(string name)
{
return UnRegistT(buttons, name);
}
public Button GetButton(string name)
{
if (buttons.ContainsKey(name))
return buttons[name];
return null;
}
// Text
public bool RegistText(string name, Text text)
{
return RegistT(texts, name, text);
}
public bool UnRegistText(string name)
{
return UnRegistT(texts, name);
}
public Text GetText(string name)
{
if (texts.ContainsKey(name))
return texts[name];
return null;
}
// Slider
public bool RegistSlider(string name, Slider slid)
{
return RegistT(sliders, name, slid);
}
public bool UnRegistSlider(string name)
{
return UnRegistT(sliders, name);
}
public Slider GetSlider(string name)
{
if (sliders.ContainsKey(name))
return sliders[name];
return null;
}
// Image
public bool RegistImage(string name, Image image)
{
return RegistT(images, name, image);
}
public bool UnRegistImage(string name)
{
return UnRegistT(images, name);
}
public Image GetImage(string name)
{
if (images.ContainsKey(name))
return images[name];
return null;
}
// ImputFiled
public bool RegistInputField(string name, InputField inputFiled)
{
return RegistT(inputs, name, inputFiled);
}
public bool UnRegistInputField(string name)
{
return UnRegistT(inputs, name);
}
public InputField GetInputField(string name)
{
if (inputs.ContainsKey(name))
return inputs[name];
return null;
}
// PanelBase
public bool RegistPanelBase(string name, PanelBase panelBase)
{
return RegistT(panelbases, name, panelBase);
}
public bool UnRegistPanelBase(string name)
{
return UnRegistT(panelbases, name);
}
public PanelBase GetPanelBase(string name)
{
if (panelbases.ContainsKey(name))
return panelbases[name];
return null;
}
}
}
// UiControlRegistor.cs
// Author: Iann
using UnityEngine;
namespace Assets.Script.Frame
{
/// <summary>
/// 界面控件注册器的基类
/// </summary>
class UiControlRegistor : MonoBehaviour
{
/// <summary>
/// 指定的界面控件容器
/// </summary>
public UiControlContainer PointedContainer = null;
/// <summary>
/// 注册后立即删除本注册器, 用于多次加载的选项
/// </summary>
public bool removeThisWhenAwake = false;
/// <summary>
/// 唤醒函数, 我们的注册就是在这个函数中实现的
/// </summary>
public virtual void Awake()
{
#if USE_LOG && LOG_FRAME_UI
Debug.Log("UiBehaviour(" + name + ").Awake");
#endif
container.RegistObject(name, gameObject);
if (removeThisWhenAwake)
{
DestroyImmediate(this);
}
}
/// <summary>
/// 销毁函数, 反注册写在这个函数中
/// </summary>
public virtual void Destroy()
{
#if USE_LOG && LOG_FRAME_UI
Debug.Log("UiBehaviour(" + name + ").Destroy");
#endif
if (!removeThisWhenAwake)
container.UnRegistObject(name);
}
/// <summary>
/// 如果制定了目标容器就返回制定的目标容器,
/// 否则依次向跟节点查找容器, 返回路径上的第一个容器作为目标容器
/// </summary>
public UiControlContainer container { get { return PointedContainer ?
PointedContainer : transform.GetComponentInParent<UiControlContainer>(); } }
}
}
// UiControlContainer.cs
// Author: Iann
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
namespace Assets.Script.Frame
{
/// <summary>
/// 控件容器
/// </summary>
public class UiControlContainer : MonoBehaviour
{
//各种类型的器皿
private Dictionary<string, Button> buttons = new Dictionary<string, Button>();
private Dictionary<string, Image> images = new Dictionary<string, Image>();
private Dictionary<string, InputField> inputs = new Dictionary<string, InputField>();
private Dictionary<string, Text> texts = new Dictionary<string, Text>();
private Dictionary<string, Slider> sliders = new Dictionary<string, Slider>();
private Dictionary<string, GameObject> objects = new Dictionary<string, GameObject>();
private Dictionary<string, PanelBase> panelbases = new Dictionary<string, PanelBase>();
/// <summary>
/// 泛型的注册函数
/// </summary>
/// <typeparam name="T">注册的类型</typeparam>
/// <param name="datas">注册用到的器皿</param>
/// <param name="name">控件名称</param>
/// <param name="unit">控件Instance</param>
/// <returns></returns>
private bool RegistT<T>(Dictionary<string, T> datas, string name, T unit)
{
if (datas.ContainsKey(name))
{
Debug.LogError("name(" + name + ") already exist");
return false;
}
datas.Add(name, unit);
return true;
}
/// <summary>
/// 泛型的反注册函数
/// </summary>
/// <typeparam name="T">反注册的类型</typeparam>
/// <param name="datas">反注册用到的器皿</param>
/// <param name="name">控件名称</param>
/// <returns></returns>
private bool UnRegistT<T>(Dictionary<string, T> datas, string name)
{
if (!datas.ContainsKey(name))
{
Debug.LogError("name not exist");
return false;
}
datas.Remove(name);
return true;
}
/// <summary>
/// 注册GameObject
/// </summary>
/// <param name="name">GameObject的名字</param>
/// <param name="obj">实例</param>
/// <returns></returns>
public bool RegistObject(string name, GameObject obj)
{
return RegistT(objects, name, obj);
}
/// <summary>
/// 反注册GameObject
/// </summary>
/// <param name="name">GameObject的名字</param>
/// <returns></returns>
public bool UnRegistObject(string name)
{
return UnRegistT(objects, name);
}
/// <summary>
/// 获得GameObeject
/// </summary>
/// <param name="name">GameObject的名字</param>
/// <returns></returns>
public GameObject GetObject(string name)
{
if (objects.ContainsKey(name))
return objects[name];
return null;
}
// Button
public bool RegistButton(string name, Button button)
{
return RegistT(buttons, name, button);
}
public bool UnRegistButton(string name)
{
return UnRegistT(buttons, name);
}
public Button GetButton(string name)
{
if (buttons.ContainsKey(name))
return buttons[name];
return null;
}
// Text
public bool RegistText(string name, Text text)
{
return RegistT(texts, name, text);
}
public bool UnRegistText(string name)
{
return UnRegistT(texts, name);
}
public Text GetText(string name)
{
if (texts.ContainsKey(name))
return texts[name];
return null;
}
// Slider
public bool RegistSlider(string name, Slider slid)
{
return RegistT(sliders, name, slid);
}
public bool UnRegistSlider(string name)
{
return UnRegistT(sliders, name);
}
public Slider GetSlider(string name)
{
if (sliders.ContainsKey(name))
return sliders[name];
return null;
}
// Image
public bool RegistImage(string name, Image image)
{
return RegistT(images, name, image);
}
public bool UnRegistImage(string name)
{
return UnRegistT(images, name);
}
public Image GetImage(string name)
{
if (images.ContainsKey(name))
return images[name];
return null;
}
// ImputFiled
public bool RegistInputField(string name, InputField inputFiled)
{
return RegistT(inputs, name, inputFiled);
}
public bool UnRegistInputField(string name)
{
return UnRegistT(inputs, name);
}
public InputField GetInputField(string name)
{
if (inputs.ContainsKey(name))
return inputs[name];
return null;
}
// PanelBase
public bool RegistPanelBase(string name, PanelBase panelBase)
{
return RegistT(panelbases, name, panelBase);
}
public bool UnRegistPanelBase(string name)
{
return UnRegistT(panelbases, name);
}
public PanelBase GetPanelBase(string name)
{
if (panelbases.ContainsKey(name))
return panelbases[name];
return null;
}
}
}