版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/leonardo_Davinci/article/details/78401907
1.为什么要使用UI层级管理框架?
根据我个人写的UI层级总结出:在一般UI界面的 Canvas 下有多个Panel,每个Panel下又有很多个需要操作的控件(Image、Text、inputField、Button)等,
因此要去管理如此多的事件处理非常繁琐,UI的层级结构刚好适合用一套框架来管理 :Canvas--->Panel--->(控件)
例:
第一步:给需要监听鼠标事件的控件添加监听脚本
用一个脚本代替 控件在Inspector中留下的OnClick方法(例:Button的OnClick需要去在脚本中寻找相对应的方法,如果脚本多了,寻找方法困难,而且不利于扩展)
因此我用了一个 OnTriggerEvent.cs 的脚本来执行相应的点击事件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class OnTriggerEvent : EventTrigger {
//通过委托事件让UIScene来分配事件
public delegate void ClickListener();
public event ClickListener onBeginDrag;
public event ClickListener onDrag;
public event ClickListener onEndDrag;
public event ClickListener onPointerClick;
public event ClickListener onPointerUp;
///UI的相关监听//鼠标进入
public override void OnBeginDrag(PointerEventData eventdata)
{
if (onBeginDrag != null)
onBeginDrag();
}
public override void OnDrag(PointerEventData eventdata)
{
if (onDrag != null)
onDrag();
}
public override void OnEndDrag(PointerEventData eventdata)
{
if (onEndDrag != null)
onEndDrag();
}
public override void OnPointerClick(PointerEventData eventdata)
{
if (onPointerClick != null)
onPointerClick();
}
public override void OnPointerUp(PointerEventData eventdata)
{
if (onPointerUp != null)
onPointerUp();
}
}
第二步:给Panel添加脚本管理其下面需要监听的各个控件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIscene : MonoBehaviour {
/// <summary>
/// 管理所有需要监听的子物体
/// </summary>
Dictionary<string,OnTriggerEvent> items=new Dictionary<string, OnTriggerEvent>();
// Use this for initialization
public void Start () {
Init();
}
/// <summary>
/// 根据名字在字典当中获取子物体
/// </summary>
public OnTriggerEvent GetTrigger(string name)
{
if (items.ContainsKey(name))
return items[name];
return null;
}
public void Init()
{
//调用Find方法找到这个Panel下面带有OnTriggerEvent组件的所有子物体
Find(transform);
}
//递归查找子物体
public void Find(Transform t)
{
OnTriggerEvent item = t.GetComponent<OnTriggerEvent>();
if (item != null)
{
string name = item.gameObject.name;
if (!items.ContainsKey(name))
{
items.Add(name, item);
}
}
for (int i = 0; i < t.childCount; i++)
{
Find(t.GetChild(i));
}
}
}
第三步:给Canvas添加管理各个Panel的脚本 UIManager.cs
可以创建一个单例作为全局管理的类
如:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIPanel<T> : MonoBehaviour where T:Component{
private static T target;
public static T Intance
{
get{
target = GameObject.FindObjectOfType(typeof(T)) as T;
if (target == null)
{
GameObject go = new GameObject();
target = go.AddComponent<T>();
}
return target;
}
}
}
UIManager继承这个单例,方便使用
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//因为有些Panel的名称复杂,所以通过静态类、字段存一些Panel的名称,方便我们索引
public class UISceneName
{
public const string Panel_login = "Panel_Login";
public const string Panel_ChooseAndEnter = "Panel_ChooseAndEnter";
public const string Panel_CreateCharacter = "Panel_CreateCharacter";
public const string Panel_Main = "Panel_Main";
public const string Panel_Hero="Panel_Hero";
// public const string Panel_Register="Panel_Register";
// public const string
}
public class UIManager : UIPanel<UIManager> {
//创建一个字典来保存所有 Panel
Dictionary<string,UIscene> scenes = new Dictionary<string,UIscene>();
public void Init()
{
UIscene[] items = GameObject.FindObjectsOfType<UIscene>();
for (int i = 0; i < items.Length; i++)
{
UIscene go =items[i];
if (!scenes.ContainsKey(go.name))
{
scenes.Add(go.name, go);
go.gameObject.SetActive(false);
}
}
}
//获取UIscene
public UIscene GetUIscene(string name)
{
if (scenes.ContainsKey(name))
{
return scenes[name];
}
return null;
}
//对UIScene组件的Panel是否激活
public void IsActive(string name,bool isActive)
{
GameObject go = scenes[name].gameObject;
if (go == null)
{
Debug.Log("你要查找的物体丢");
return;
}
go.gameObject.SetActive(isActive);
}
//展现登录界面的UIScene
public void ShowUI()
{
IsActive(UISceneName.Panel_login, true);
}
}
第四步:前面三步都是管理思想,并提供了很多接口,
初始化整个UI
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Init : MonoBehaviour {
// Use this for initialization
void Start () {
UIManager.Intance.Init();
UIManager.Intance.ShowUI();
}
}
第五步:外部的使用:通过继承UIScene的到整个Panel下面的所有需要监听的控件
如:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ToMain : UIscene {
private OnTriggerEvent Button_ToMain;
// Use this for initialization
void Start () {
base.Start();
Button_ToMain = GetTrigger("Button_ToMain");
//给返回按钮绑定事件
Button_ToMain.onPointerClick += HeroToMain;
}
//返回到主界面
private void HeroToMain()
{
//关闭英雄界面
UIManager.Intance.IsActive(UISceneName.Panel_Hero, false);
//打开主界面
UIManager.Intance.IsActive(UISceneName.Panel_Main, true);
}
}