特别提示: 本系列基于Unity 2019.4.8,框架版本GameFramework 2021.05.31
本系列博客地址: 传送门
Game Framework提供了管理界面和界面组的功能,如显示隐藏界面、激活界面、改变界面层级等。不论是 Unity 内置的 UGUI 还是其它类型的 UI 插件(如 NGUI),只要派生自 UIFormLogic 类并实现自己的界面类即可使用。界面使用结束后可以不立刻销毁,从而等待下一次重新使用。
一、创建UI脚本
UI预制体就不用说怎么制作了吧,UI脚本需要继承UIFormLogic 挂在UI上,父类有很多虚方法我们按需求重写,生命周期跟MonoBehaviour的差不多
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityGameFramework.Runtime;
using UnityEngine.UI;
public class UIForm_Setting : UIFormLogic
{
public Button Btn_StartGame;
public Button Btn_Close;
UIComponent uiComponent;
/// <summary>
/// 界面初始化
/// </summary>
/// <param name="userData"></param>
protected override void OnInit(object userData)
{
base.OnInit(userData);
uiComponent = GameEntry.GetComponent<UIComponent>();
Btn_Close.onClick.AddListener(() =>
{
uiComponent.OpenUIForm("Assets/Prefabs/Canvas_Menu.prefab", "Default");
uiComponent.CloseUIForm(this.UIForm);
});
}
/// <summary>
/// 界面打开
/// </summary>
/// <param name="userData"></param>
protected override void OnOpen(object userData)
{
base.OnOpen(userData);
Log.Error($"眼睛一睁,{Name}就打开了");
}
/// <summary>
/// 界面关闭
/// </summary>
/// <param name="isShutdown"></param>
/// <param name="userData"></param>
protected override void OnClose(bool isShutdown, object userData)
{
base.OnClose(isShutdown, userData);
Log.Error($"眼睛一闭,{Name}就关闭了");
}
}
二、设置UI分组
在UI组件上设置分组,UI会被加载到对应的分组里
三、常见用法
获取UI组件
uiComponent = GameEntry.GetComponent<UIComponent>();
打开UI界面(隐藏的UI会被显示,场景不存在的UI会先加载然后显示)
uiComponent.OpenUIForm("Assets/Prefabs/Canvas_Menu.prefab", "Default");
获取UI界面
uiComponent.GetUIForm("Assets/Prefabs/Canvas_Setting.prefab");
关闭UI界面
uiComponent.CloseUIForm(this.UIForm);
提示 : 打开 ,获取,关闭等有多个重载,另外也可自写拓展方法
四、补充
让我们对之前的流程,事件以及UI脚本加亿点点细节,使其具有连贯性
1、制作两个UI,游戏菜单界面跟游戏设置界面,脚本功能大致就是点击设置出现设置界面,点击取消返回菜单界面
UIForm_Menu.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityGameFramework.Runtime;
using UnityEngine.UI;
public class UIForm_Menu : UIFormLogic
{
public Button Btn_StartGame;
public Button Btn_Setting;
UIComponent uiComponent;
/// <summary>
/// 界面初始化
/// </summary>
/// <param name="userData"></param>
protected override void OnInit(object userData)
{
base.OnInit(userData);
uiComponent = GameEntry.GetComponent<UIComponent>();
Btn_Setting.onClick.AddListener(() =>
{
uiComponent.OpenUIForm("Assets/Prefabs/Canvas_Setting.prefab", "Default");
uiComponent.CloseUIForm(this.UIForm);
});
}
/// <summary>
/// 界面打开
/// </summary>
/// <param name="userData"></param>
protected override void OnOpen(object userData)
{
base.OnOpen(userData);
Log.Error($"眼睛一睁,{Name}就打开了");
}
/// <summary>
/// 界面关闭
/// </summary>
/// <param name="isShutdown"></param>
/// <param name="userData"></param>
protected override void OnClose(bool isShutdown, object userData)
{
base.OnClose(isShutdown, userData);
Log.Error($"眼睛一闭,{Name}就关闭了");
}
}
UIForm_Setting.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityGameFramework.Runtime;
using UnityEngine.UI;
public class UIForm_Setting : UIFormLogic
{
public Button Btn_Confirm;
public Button Btn_Cancel;
UIComponent uiComponent;
public Toggle Toggle_Music;
public Slider Slider_Music;
public Toggle Toggle_SoundEffect;
public Slider Slider_SoundEffect;
public Toggle Toggle_UISoundEffect;
public Slider Slider_UISoundEffect;
/// <summary>
/// 界面初始化
/// </summary>
/// <param name="userData"></param>
protected override void OnInit(object userData)
{
base.OnInit(userData);
uiComponent = GameEntry.GetComponent<UIComponent>();
Btn_Cancel.onClick.AddListener(() =>
{
uiComponent.OpenUIForm("Assets/Prefabs/Canvas_Menu.prefab", "Default");
uiComponent.CloseUIForm(this.UIForm);
});
}
/// <summary>
/// 界面打开
/// </summary>
/// <param name="userData"></param>
protected override void OnOpen(object userData)
{
base.OnOpen(userData);
Log.Error($"眼睛一睁,{Name}就打开了");
}
/// <summary>
/// 界面关闭
/// </summary>
/// <param name="isShutdown"></param>
/// <param name="userData"></param>
protected override void OnClose(bool isShutdown, object userData)
{
base.OnClose(isShutdown, userData);
Log.Error($"眼睛一闭,{Name}就关闭了");
}
}
2、KeyCodePressEventArgs事件增加UserData字段,方便我们传递数据
3、ProcedureExample脚本改成按下空格切换ProcedureMenu菜单流程
4、ProcedureMenu里打开我们的Menu菜单,这里使用了GF内置的UI事件OpenUIFormSuccessEventArgs,并且传入了一段字符串
using GameFramework.Event;
using GameFramework.Procedure;
using UnityGameFramework.Runtime;
using ProcedureOwner = GameFramework.Fsm.IFsm<GameFramework.Procedure.IProcedureManager>;
using System;
namespace GameFrameworkExample
{
public class ProcedureMenu : ProcedureBase
{
UIComponent uiComponent;
EventComponent eventComponent;
protected override void OnEnter(ProcedureOwner procedureOwner)
{
base.OnEnter(procedureOwner);
Log.Error($"当前流程:{GetType()}");
eventComponent = GameEntry.GetComponent<EventComponent>();
uiComponent = GameEntry.GetComponent<UIComponent>();
eventComponent.Subscribe(OpenUIFormSuccessEventArgs.EventId, OpenUIFormSuccess);
uiComponent.OpenUIForm("Assets/Prefabs/Canvas_Menu.prefab", "Default", "打开UI成功事件");
}
protected override void OnUpdate(ProcedureOwner procedureOwner, float elapseSeconds, float realElapseSeconds)
{
base.OnUpdate(procedureOwner, elapseSeconds, realElapseSeconds);
}
protected override void OnLeave(ProcedureOwner procedureOwner, bool isShutdown)
{
base.OnLeave(procedureOwner, isShutdown);
eventComponent.Unsubscribe(OpenUIFormSuccessEventArgs.EventId, OpenUIFormSuccess);
}
void OpenUIFormSuccess(object sender, GameEventArgs e)
{
OpenUIFormSuccessEventArgs openUIFormSuccessEventArgs = (OpenUIFormSuccessEventArgs)e;
Log.Error($"{openUIFormSuccessEventArgs.UserData}:{DateTime.Now}");
}
}
}
只要我们没有取消订阅OpenUIFormSuccessEventArgs,打开UI的时候都会走绑定的回调函数,在ProcedureMenu里打开UI时 ,我们有传递字符串,后续的打开没有传递数据,所以后面的DeBug输出只有时间信息
5、为了避免重复获取组件,新增Component脚本挂在场景GameFramework上,统一获取组件并且直接静态调用,然后将我们之前获取组件的地方全部改一下
对后续组件的讲解,我会逐步加入到我们的Demo中,助于加深对GF的理解