凡科快图可以商用吗,南通网站流量优化,贵阳网站开发外包,h5 WordPress推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址QQ群#xff1a;398291828 大家好#xff0c;我是佛系工程师☆恬静的小魔龙☆#xff0c;不定时更新Unity开发技巧#xff0c;觉得有用记得一键三连哦。
一、前言
【GameFramework框架】系列教程目录#xff1a;… 推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址QQ群398291828 大家好我是佛系工程师☆恬静的小魔龙☆不定时更新Unity开发技巧觉得有用记得一键三连哦。
一、前言
【GameFramework框架】系列教程目录 https://blog.csdn.net/q764424567/article/details/135831551
二、正文
2-1、介绍
界面UI提供管理UI界面和界面组的功能比如显示界面、激活界面、改变界面层级等。
界面UI为Unity的GUI系统提供了灵活和强大的功能帮助开发者快速构建游戏UI。
还可以与现有的Unity 的UI插件如NGUI、FGUI及GUI系统UGUI无缝集成只要派生自UIFormLogic类并实现自己的界面类即可使用。
界面使用结束后可以不立即销毁等待下一次使用。
2-2、使用说明
1UIComponent组件的编辑器面板 UIComponent组件的编辑器面板配置UI的回调事件、UI界面组、界面对象池参数以及辅助器的设置。
UIGroups UI界面的管理层级的管理是不可少的而UIGroups就是处理不同页面的层级。
在同一个Group中可以打开不同的页面。
不同的Group组中的UI的层级不一样的比如UI我们可以这么分
Scene层最底层场景UI一般置于场景之上界面UI之下如点击建筑查看建筑信息—Background层背景UI如:主界面一般情况下用户不能主动关闭永远处于其它Ul的最底层Normal层普通UI一级、二级、三级等窗口一般由用户点击打开的多级窗口lnfo层信息UI—如跑马灯、广播等—般永远置于用户打开窗口顶层Tip层提示UI如错误弹窗网络连接弹窗等Top层顶层UI如场景加载
2配置UI界面配置表
配置表 界面配置表中配置了UI界面的Id、资源名AssetName、UI组名UIGroupName、是否允许多个实例allow multiple instances以及是否覆盖UIForm。
预制体
参数及枚举
这些参数的设置可以保证框架在打开UI界面时可以找到UI界面的相关参数。
在UIFormId.cs中添加枚举注意枚举的Id要和配置表的id一致
namespace StarForce
{/// summary/// 界面编号。/// /summarypublic enum UIFormId : byte{Undefined 0,/// summary/// 弹出框。/// /summaryDialogForm 1,/// summary/// 主菜单。/// /summaryMenuForm 100,/// summary/// 设置。/// /summarySettingForm 101,/// summary/// 关于。/// /summaryAboutForm 102,}
}3打开、获取、关闭UI界面
UI的相关操作代码示例如下
//打开
GameEntry.UI.OpenUIForm(UIFormId.MenuForm);
//获取
GameEntry.UI.GetUIForm(UIFormId.MenuForm);
//关闭
GameEntry.UI.CloseUIForm(uiForm);这里只说明如何打开UI具体UI的加载过程将在下一节详细分析。
4传递参数
打开UI传参数数组或者自己指定实体类。
传参
GameEntry.UI.OpenUIForm(UIFormId.MainForm, new object[]{xxx,xxx});UI界面接收参数
public class MenuForm : UGuiForm
{protected override void OnOpen(object userData){base.OnOpen(userData);var args (object[])userData;//......}
}5实现UI界面的事件
以MenuForm.cs为例继承UGuiForm后实现UI事件即可
using UnityEngine;
using UnityGameFramework.Runtime;namespace StarForce
{public class MenuForm : UGuiForm{[SerializeField]private GameObject m_QuitButton null;private ProcedureMenu m_ProcedureMenu null;public void OnStartButtonClick(){m_ProcedureMenu.StartGame();}public void OnSettingButtonClick(){GameEntry.UI.OpenUIForm(UIFormId.SettingForm);}public void OnAboutButtonClick(){GameEntry.UI.OpenUIForm(UIFormId.AboutForm);}public void OnQuitButtonClick(){GameEntry.UI.OpenDialog(new DialogParams(){Mode 2,Title GameEntry.Localization.GetString(AskQuitGame.Title),Message GameEntry.Localization.GetString(AskQuitGame.Message),OnClickConfirm delegate (object userData) { UnityGameFramework.Runtime.GameEntry.Shutdown(ShutdownType.Quit); },});}#if UNITY_2017_3_OR_NEWERprotected override void OnOpen(object userData)
#elseprotected internal override void OnOpen(object userData)
#endif{base.OnOpen(userData);m_ProcedureMenu (ProcedureMenu)userData;if (m_ProcedureMenu null){Log.Warning(ProcedureMenu is invalid when open MenuForm.);return;}m_QuitButton.SetActive(Application.platform ! RuntimePlatform.IPhonePlayer);}#if UNITY_2017_3_OR_NEWERprotected override void OnClose(bool isShutdown, object userData)
#elseprotected internal override void OnClose(bool isShutdown, object userData)
#endif{m_ProcedureMenu null;base.OnClose(isShutdown, userData);}}
}绑定事件
2-3、实现及代码分析
接下来就来分析一下GameFramework框架在GameEntry.UI.OpenUIForm(UIFormId.MenuForm)中做了那些事情吧。
1打开UI界面过程及代码分析
打开UI界面
GameEntry.UI.OpenUIForm(UIFormId.MenuForm, this);获取数据表中的数据传递给uiComponent.OpenUIForm()函数
public static int? OpenUIForm(this UIComponent uiComponent, UIFormId uiFormId, object userData null)
{return uiComponent.OpenUIForm((int)uiFormId, userData);
}public static int? OpenUIForm(this UIComponent uiComponent, int uiFormId, object userData null)
{IDataTableDRUIForm dtUIForm GameEntry.DataTable.GetDataTableDRUIForm();DRUIForm drUIForm dtUIForm.GetDataRow(uiFormId);if (drUIForm null){Log.Warning(Can not load UI form {0} from data table., uiFormId.ToString());return null;}string assetName AssetUtility.GetUIFormAsset(drUIForm.AssetName);if (!drUIForm.AllowMultiInstance){if (uiComponent.IsLoadingUIForm(assetName)){return null;}if (uiComponent.HasUIForm(assetName)){return null;}}return uiComponent.OpenUIForm(assetName, drUIForm.UIGroupName, Constant.AssetPriority.UIFormAsset, drUIForm.PauseCoveredUIForm, userData);
}资源路径的获取
string assetName AssetUtility.GetUIFormAsset(drUIForm.AssetName);
// 获取到预制体的路径
public static string GetUIFormAsset(string assetName)
{return Utility.Text.Format(Assets/GameMain/UI/UIForms/{0}.prefab, assetName);
}调用UIComponent组件封装的m_UIManager的API
/// summary
/// 打开界面。
/// /summary
/// param nameuiFormAssetName界面资源名称。/param
/// param nameuiGroupName界面组名称。/param
/// param namepriority加载界面资源的优先级。/param
/// param namepauseCoveredUIForm是否暂停被覆盖的界面。/param
/// param nameuserData用户自定义数据。/param
/// returns界面的序列编号。/returns
public int OpenUIForm(string uiFormAssetName, string uiGroupName, int priority, bool pauseCoveredUIForm, object userData)
{return m_UIManager.OpenUIForm(uiFormAssetName, uiGroupName, priority, pauseCoveredUIForm, userData);
}OK最后一步了属于是我们找到UIManager.cs脚本来看一下
/// summary
/// 打开界面。
/// /summary
/// param nameuiFormAssetName界面资源名称。/param
/// param nameuiGroupName界面组名称。/param
/// param namepriority加载界面资源的优先级。/param
/// param namepauseCoveredUIForm是否暂停被覆盖的界面。/param
/// param nameuserData用户自定义数据。/param
/// returns界面的序列编号。/returns
public int OpenUIForm(string uiFormAssetName, string uiGroupName, int priority, bool pauseCoveredUIForm, object userData)
{if (m_ResourceManager null){throw new GameFrameworkException(You must set resource manager first.);}if (m_UIFormHelper null){throw new GameFrameworkException(You must set UI form helper first.);}if (string.IsNullOrEmpty(uiFormAssetName)){throw new GameFrameworkException(UI form asset name is invalid.);}if (string.IsNullOrEmpty(uiGroupName)){throw new GameFrameworkException(UI group name is invalid.);}UIGroup uiGroup (UIGroup)GetUIGroup(uiGroupName);if (uiGroup null){throw new GameFrameworkException(Utility.Text.Format(UI group {0} is not exist., uiGroupName));}int serialId m_Serial;UIFormInstanceObject uiFormInstanceObject m_InstancePool.Spawn(uiFormAssetName);if (uiFormInstanceObject null){m_UIFormsBeingLoaded.Add(serialId, uiFormAssetName);m_ResourceManager.LoadAsset(uiFormAssetName, priority, m_LoadAssetCallbacks, OpenUIFormInfo.Create(serialId, uiGroup, pauseCoveredUIForm, userData));}else{InternalOpenUIForm(serialId, uiFormAssetName, uiGroup, uiFormInstanceObject.Target, pauseCoveredUIForm, false, 0f, userData);}return serialId;
}最后判断是否存在这个UI界面的实例有的话加载没有的话通过Resource模块进行加载。
害最后还得是Resource模块进行加载。
2UIManager.cs
UlManager类是整个UI框架的总管理器负责UI的所有调度如打开关闭激活等。
UIManager使用了ResourceManager来加载界面预制体资源等所以UI框架只支持异步加载不能同步打开UI界面或传参。UIManager使用了ObjectPool来处理UI界面的复用和回收。让我们完全不用担心UI界面的垃圾处理问题大胆放心的使用UI框架。UIManager使用了Group组的方式类存储和维护UI界面非常方便我们管理和扩展界面功能。UIFormHelper是处理界面实例化初始化和释放的辅助器方便我们在实际使用时扩展UlManager。
namespace GameFramework.UI
{/// 界面管理器。internal sealed partial class UIManager : GameFrameworkModule, IUIManager{private readonly Dictionarystring, UIGroup m_UIGroups;//UI界面组private IResourceManager m_ResourceManager;//资源管理器private IObjectPoolUIFormInstanceObject m_InstancePool;//界面实例对象池private IUIFormHelper m_UIFormHelper;//界面辅助器Helper/// 增加界面组。public bool AddUIGroup(string uiGroupName, int uiGroupDepth, IUIGroupHelper uiGroupHelper)/// 打开界面。public int OpenUIForm(string uiFormAssetName, string uiGroupName, object userData)/// 关闭界面public void CloseUIForm(IUIForm uiForm)/// 初始化打开UIFormprivate void InternalOpenUIForm(int serialId, string uiFormAssetName, UIGroup uiGroup, object uiFormInstance, bool pauseCoveredUIForm, bool isNewInstance, float duration, object userData)/// 异步加载UI预制体回调private void LoadAssetSuccessCallback(string uiFormAssetName, object uiFormAsset, float duration, object userData)}
}4UIForm、UIFormLogic、UGuiForm
每个单独的页面是一个UIForm它继承自IUIForm
/// summary
/// 界面。
/// /summary
public sealed class UIForm : MonoBehaviour, IUIForm
{private UIFormLogic m_UIFormLogic;/// 获取界面逻辑。/// 界面回收。public void OnRecycle(){m_UIFormLogic.OnRecycle();}/// 界面打开。public void OnOpen(object userData){m_UIFormLogic.OnOpen(userData);}/// 界面关闭。public void OnClose(bool isShutdown, object userData){m_UIFormLogic.OnClose(isShutdown, userData);}/// 界面暂停。public void OnPause(){m_UIFormLogic.OnPause();}/// 界面暂停恢复。public void OnResume(){m_UIFormLogic.OnResume();}/// 界面遮挡。public void OnCover(){m_UIFormLogic.OnCover();}/// 界面遮挡恢复。public void OnReveal(){m_UIFormLogic.OnReveal();}/// 界面激活。public void OnRefocus(object userData){m_UIFormLogic.OnRefocus(userData);}
}UIForm只是一个UI窗口所有的界面逻辑都写在UlFormLogic中。
不管是UGUINGUI还是FGUI等等只要继承自UIFormLogic就可以了。
比如Starforce中的UGuiForm
namespace StarForce
{public abstract class UGuiForm : UIFormLogic{protected Canvas m_CachedCanvas null;protected CanvasGroup m_CanvasGroup null;//自定义函数public void Close(bool ignoreFade)public void PlayUISound(int uiSoundId)public static void SetMainFont(Font mainFont)//生命周期函数protected override void OnInit(object userData)protected override void OnRecycle()protected override void OnOpen(object userData)protected override void OnClose(bool isShutdown, object userData)protected override void OnPause()protected override void OnResume()protected override void OnCover()protected override void OnReveal()protected override void OnRefocus(object userData)protected override void OnUpdate(float elapseSeconds, float realElapseSeconds)protected override void OnDepthChanged(int uiGroupDepth, int depthInUIGroup)}
}我们可以根据UGuiFormLogic的结构来实现我们自己的NGuiFormLogic或者FGuiFormLogic等等。
三、后记
如果觉得本篇文章有用别忘了点个关注关注不迷路持续分享更多Unity干货文章。 你的点赞就是对博主的支持有问题记得留言
博主主页有联系方式。
博主还有跟多宝藏文章等待你的发掘哦
专栏方向简介Unity3D开发小游戏小游戏开发教程分享一些使用Unity3D引擎开发的小游戏分享一些制作小游戏的教程。Unity3D从入门到进阶入门从自学Unity中获取灵感总结从零开始学习Unity的路线有C#和Unity的知识。Unity3D之UGUIUGUIUnity的UI系统UGUI全解析从UGUI的基础控件开始讲起然后将UGUI的原理UGUI的使用全面教学。Unity3D之读取数据文件读取使用Unity3D读取txt文档、json文档、xml文档、csv文档、Excel文档。Unity3D之数据集合数据集合数组集合数组、List、字典、堆栈、链表等数据集合知识分享。Unity3D之VR/AR虚拟仿真开发虚拟仿真总结博主工作常见的虚拟仿真需求进行案例讲解。Unity3D之插件插件主要分享在Unity开发中用到的一些插件使用方法插件介绍等Unity3D之日常开发日常记录主要是博主日常开发中用到的用到的方法技巧开发思路代码分享等Unity3D之日常BUG日常记录记录在使用Unity3D编辑器开发项目过程中遇到的BUG和坑让后来人可以有些参考。