3.提示面板
3.1 拼面板
创建普通通用按钮
创建窗口组件和窗口内部组件。对着示意图拼。命名规则要符合窗口的命名规则。
选择好资源和代码的发布的路径 进行发布
注意:对于一个面板我们要用到两个代码,一个是FGUI发布的代码,用于自动获取对象的,另一个是继承WIndow类的代码,用来写逻辑的。这样每次发布代码,也不会覆盖掉逻辑。两套代码放到不同的路径下
3.2 功能制作
导入字体到Resources文件夹下 把音乐文件设置为导出 在UIManager构造函数中设置字体和音乐
//默认字体
UIConfig.defaultFont = "UI/STHUPO";
//默认音效
UIPackage.AddPackage("UI/Public");
UIConfig.buttonSound = (NAudioClip)UIPackage.GetItemAssetByURL("ui://Public/btnMusic");
UIManager构造函数中绑定注册所有自定义类
//注册相关的代码
LoginBinder.BindAll();
在UIManager添加加载组件方法。传入包名和组件名。遍历加载包和依赖包。创建组件并返回。
/// <summary>
/// 加载组件
/// </summary>
/// <param name="packageName">包名</param>
/// <param name="componentName">组件名</param>
/// <returns></returns>
public GComponent LoadComponent(string packageName, string componentName)
{
//加载包
UIPackage package = UIPackage.AddPackage("UI/" + packageName);
//加载依赖包
foreach (var item in package.dependencies)
{
UIPackage.AddPackage("UI/" + item["name"]);
}
GComponent component = UIPackage.CreateObject(packageName, componentName).asCom;
//component.MakeFullScreen();
return component;
}
创建TipWindow类 继承Window 注意让FGUI发布出来的代码加上前缀重新发布防止重名
public class TipWindow : Window
{
}
重写初始化方法中加载TipWindow对应的UI组件并设置为内容面板,将内容面板设置为全屏显示, 设置该窗口为模态(禁止和其他窗口交互)
protected override void OnInit()
{
base.OnInit();
// 加载TipWindow对应的UI组件并设置为内容面板
this.contentPane = UIManager.Instance.LoadComponent("Login", "TipWindow");
// 将内容面板设置为全屏显示
this.contentPane.MakeFullScreen();
// 设置该窗口为模态(禁止和其他窗口交互)
this.modal = true;
}
创建公共改变提示信息的方法,把当前Window的contentPane转成UI_TipWindow得到其frame中的文本并设置
public void ChangeInfo(string info)
{
// 通过窗口关联的组件转化成对应的组件拓展类(因为在管理器中注册了,所以可以转换类型)
// 然后获取其中的组件或元件,并修改其内容
(this.contentPane as UI_TipWindow).m_frame.m_txtInfo.text = info;
}
给提示窗口添加显示和隐藏动效。直接右键空白区域改变透明度让提示窗口淡入淡出。
重写显示和隐藏动效的方法。在动画播完的回调后再调用基类的显示和隐藏动效的方法。否则因为先调用了基类方法会先被显示或隐藏则动效不生效。
protected override void DoShowAnimation()
{
// 播放内容面板上名为"show"的过渡动画,并在动画完成后调用基类的DoShowAnimation方法
this.contentPane.GetTransition("show").Play(base.DoShowAnimation);
}
protected override void DoHideAnimation()
{
// 播放内容面板上名为"hide"的过渡动画,并在动画完成后调用基类的DoHideAnimation方法
this.contentPane.GetTransition("hide").Play(base.DoHideAnimation);
}
创建Main脚本 进行提示窗口的测试
void Start()
{
TipWindow win = UIManager.Instance.ShowWindow<TipWindow>();
win.ChangeInfo("欢迎进入游戏");
}
3.3 代码
UIManager
using FairyGUI;
using Login;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIManager
{
private static UIManager instance = new UIManager();
public static UIManager Instance => instance;
//用于存储已经显示的 UI面板
private Dictionary<string, GComponent> panelDic = new Dictionary<string, GComponent>();
//用于存储已经显示的 窗口
private Dictionary<string, Window> windowDic = new Dictionary<string, Window>();
private UIManager()
{
//默认字体
UIConfig.defaultFont = "UI/STHUPO";
//默认音效
UIPackage.AddPackage("UI/Public");
UIConfig.buttonSound = (NAudioClip)UIPackage.GetItemAssetByURL("ui://Public/btnMusic");
//适配相关的设置
GRoot.inst.SetContentScaleFactor(1365, 768, UIContentScaler.ScreenMatchMode.MatchHeight);
//设置模态半透明程度
UIConfig.modalLayerColor = new Color(0, 0, 0, 0.5f);
//注册相关的代码
LoginBinder.BindAll();
}
//组件名和面板类名 是一致的
public T ShowPanel<T>(string packageName) where T:GComponent
{
Type panelType = typeof(T);
string panelName = panelType.Name;
//如果字典中有该面板的名字 证明已经创建过了 直接返回即可
if (panelDic.ContainsKey(panelName))
{
panelDic[panelName].visible = true;
return panelDic[panelName] as T;
}
//加载包和依赖包
//由于从Resources文件夹中加载包 会帮助我们判断重复没有 所以 这里既是重复执行也没什么问题
UIPackage package = UIPackage.AddPackage("UI/" + packageName);
foreach (var item in package.dependencies)
{
UIPackage.AddPackage("UI/" + item["name"]);
}
//创建组件面板
GComponent panel = UIPackage.CreateObject(packageName, panelName).asCom;
//把组件的尺寸设置的和逻辑分辨率一致
panel.MakeFullScreen();
GRoot.inst.AddChild(panel);
//和父对象建立 宽高关联 这样 分辨率变化时 面板也不会出问题
panel.AddRelation(GRoot.inst, RelationType.Size);
//进行批处理 DC优化 开关开启
panel.fairyBatching = true;
//把当前显示的面板存起来 用于之后的隐藏
panelDic.Add(panelName, panel);
//把父类转换成对应的 子类
return panel as T;
}
//显示窗口方法
public T ShowWindow<T>() where T:Window,new()
{
Type type = typeof(T);
string windowName = type.Name;
//判断有没有面板
if (windowDic.ContainsKey(windowName))
{
windowDic[windowName].Show();
return windowDic[windowName] as T;
}
//创建并显示面板
T win = new T();
win.Show();
//记录字典中
windowDic.Add(windowName, win);
return win;
}
public void HidePanel<T>(bool isDispose = false) where T:GComponent
{
Type panelType = typeof(T);
string panelName = panelType.Name;
//如果没有面板显示着 就直接返回
if (!panelDic.ContainsKey(panelName))
return;
//希望移除面板
if( isDispose )
{
//移除面板 并且从字典中移除
panelDic[panelName].Dispose();
panelDic.Remove(panelName);
}
//希望只是失活
else
{
panelDic[panelName].visible = false;
}
}
//隐藏窗口方法
public void HideWindow<T>(bool isDispose = false)
{
Type type = typeof(T);
string windowName = type.Name;
if (windowDic.ContainsKey(windowName))
{
if(isDispose)
{
windowDic[windowName].Dispose();
windowDic.Remove(windowName);
}
else
{
windowDic[windowName].Hide();
}
}
}
public T GetPanel<T>() where T:GComponent
{
Type panelType = typeof(T);
string panelName = panelType.Name;
//如果有这个面板 直接返回
if (panelDic.ContainsKey(panelName))
return panelDic[panelName] as T;
return null;
}
//得到窗口
public T GetWindow<T>() where T:Window
{
Type type = typeof(T);
string windowName = type.Name;
if (windowDic.ContainsKey(windowName))
{
return windowDic[windowName] as T;
}
return null;
}
//主要用于销毁所有面板 和 资源垃圾回收的方法
public void ClearPanel(bool isGC = false)
{
//销毁所有面板 并且清空字典
foreach (var item in panelDic.Values)
{
item.Dispose();
}
panelDic.Clear();
if(isGC)
{
//释放所有包资源
UIPackage.RemoveAllPackages();
//垃圾回收
GC.Collect();
}
}
//清除所有窗口
public void ClearWindow(bool isGC = false)
{
//销毁所有面板 并且清空字典
foreach (var item in windowDic.Values)
{
item.Dispose();
}
windowDic.Clear();
if(isGC)
{
//释放所有包资源
UIPackage.RemoveAllPackages();
//垃圾回收
GC.Collect();
}
}
/// <summary>
/// 加载组件
/// </summary>
/// <param name="packageName">包名</param>
/// <param name="componentName">组件名</param>
/// <returns></returns>
public GComponent LoadComponent(string packageName, string componentName)
{
//加载包
UIPackage package = UIPackage.AddPackage("UI/" + packageName);
//加载依赖包
foreach (var item in package.dependencies)
{
UIPackage.AddPackage("UI/" + item["name"]);
}
GComponent component = UIPackage.CreateObject(packageName, componentName).asCom;
//component.MakeFullScreen();
return component;
}
}
TipWindow
using FairyGUI; // 导入FairyGUI命名空间,用于使用UI组件
using Login; // 导入Login命名空间,用于使用登录相关功能
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TipWindow : Window
{
protected override void OnInit()
{
base.OnInit();
// 加载TipWindow对应的UI组件并设置为内容面板
this.contentPane = UIManager.Instance.LoadComponent("Login", "TipWindow");
// 将内容面板设置为全屏显示
this.contentPane.MakeFullScreen();
// 设置该窗口为模态(禁止和其他窗口交互)
this.modal = true;
}
public void ChangeInfo(string info)
{
// 通过窗口关联的组件转化成对应的组件拓展类(因为在管理器中注册了,所以可以转换类型)
// 然后获取其中的组件或元件,并修改其内容
(this.contentPane as UI_TipWindow).m_frame.m_txtInfo.text = info;
}
protected override void DoShowAnimation()
{
// 播放内容面板上名为"show"的过渡动画,并在动画完成后调用基类的DoShowAnimation方法
this.contentPane.GetTransition("show").Play(base.DoShowAnimation);
}
protected override void DoHideAnimation()
{
// 播放内容面板上名为"hide"的过渡动画,并在动画完成后调用基类的DoHideAnimation方法
this.contentPane.GetTransition("hide").Play(base.DoHideAnimation);
}
}
Main
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Main : MonoBehaviour
{
void Start()
{
TipWindow win = UIManager.Instance.ShowWindow<TipWindow>();
win.ChangeInfo("欢迎进入游戏");
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com