unity简单UI动态加载类分享

Unity UI Manager 实现
unity初学者都会把UI摆在场景内激活隐藏,来实现UI的打开关闭,这样很容易引起,UI之间的耦合. 我们可以实现一个UIManager来管理所有UI,并加载已经摆好的UI预制体和脚本,UIManager中我们只需要实现2个方法
    
Open < T > ( params object [ ] para ) //打开T类型的面板 para是任意数量的参数 Close ( string name ) / 关闭T类型名字的面板
之前写过动态加载UI的manager但是脚本要UI脚本要挂在预制体上,最近在看罗培羽的《unity3d网络游戏开发》第2版这本书的时候发现他的ui脚本和预制体是分开的,果断不能忍,抄过来改了一下感觉比我原先写的好用。 主要解决4个问题 1.UI打开关闭的动画 2.从resoure文件夹下加载UI 3.用UIManager的管理来减少面板耦合 4.UI脚本和UI预制体的分离,使ui预制体像皮肤一样,可以N个皮肤对应一个UI脚本。 现在我就来分享一些这个UIManager,有2个脚本
BasePanel.cs
    
using UnityEngine ; using System . Collections ; using DG . Tweening ; using UnityEngine . UI ; using System ; public class BasePanel : MonoBehaviour { //皮肤路径 public string skinPath ; //皮肤 public GameObject skin ; //层级 public PanelManager . Layer layer = PanelManager . Layer . Layer4 ; //初始化 public void Init ( ) { //皮肤 GameObject skinPrefab = Resources . Load < GameObject > ( skinPath ) ; skin = ( GameObject ) Instantiate ( skinPrefab ) ; } //关闭 public void Close ( ) { string name = this . GetType ( ) . ToString ( ) ; PanelManager . Close ( name ) ; } //初始化时 public virtual void OnInit ( ) { } //显示时 public virtual void OnShow ( params object [ ] para ) { } # region 可以重写动画的方法 //打开动画 public virtual void OpenAnimation ( ) { OnShowing ( ) ; Sequence mySequence = DOTween . Sequence ( ) ; mySequence . Append ( skin . transform . DOScale ( 1.1f , 0.3f ) ) . Append ( skin . transform . DOScale ( 1f , 0.2f ) ) . AppendCallback ( ( ) => { OnShowed ( ) ; } ) ; } //关闭动画 public virtual void CloseAnimation ( ) { Sequence mySequence = DOTween . Sequence ( ) ; mySequence . Append ( skin . transform . DOScale ( 0f , 0.5f ) ) . AppendCallback ( ( ) => { OnShowed ( ) ; DestroyThisPanelObj ( ) ; } ) ; } # endregion //销毁当前面板 public void DestroyThisPanelObj ( ) { string name = this . GetType ( ) . ToString ( ) ; BasePanel panel = PanelManager . panels [ name ] ; //没有打开 if ( panel == null ) { return ; } //列表 PanelManager . panels . Remove ( name ) ; //销毁 GameObject . Destroy ( panel . skin ) ; Component . Destroy ( panel ) ; } # region 面板的生命周期 /// <summary> /// 显示面板动画播放前 /// </summary> public virtual void OnShowing ( ) { } /// <summary> /// 显示面板动画播放后 /// </summary> public virtual void OnShowed ( ) { } /// <summary> /// 帧更新 /// </summary> public virtual void Update ( ) { } /// <summary>e /// 关闭动画播放前 /// </summary> public virtual void OnClosing ( ) { } /// <summary> /// 关闭动画播放后 /// </summary> public virtual void OnClosed ( ) { } # endregion /// <summary> /// 注册事件和动画 /// </summary> /// <param name="button"></param> /// <param name="tweenCallback"></param> public virtual void OnClickEventForButton ( Button button , TweenCallback tweenCallback ) { float ScaleX = button . transform . localScale . x ; button . onClick . AddListener ( ( ) => { Sequence mySequence = DOTween . Sequence ( ) ; mySequence . Append ( button . transform . DOScale ( ScaleX * 0.9f , 0.1f ) ) . Append ( button . transform . DOScale ( ScaleX , 0.1f ) ) . AppendCallback ( tweenCallback ) ; } ) ; } }
PanelManager.cs
    
using UnityEngine ; using System . Collections ; using System . Collections . Generic ; public static class PanelManager { //Layer public enum Layer { Bottom , Layer0 , Layer1 , Layer2 , Layer3 , Layer4 , Layer5 , Layer6 , Layer7 , Layer8 , Layer9 , Tip , } //层级列表 private static Dictionary < Layer , Transform > layers = new Dictionary < Layer , Transform > ( ) ; //面板列表 public static Dictionary < string , BasePanel > panels = new Dictionary < string , BasePanel > ( ) ; //结构 public static Transform root ; public static Transform canvas ; //初始化 public static void Init ( ) { root = GameObject . Find ( "Root" ) . transform ; canvas = root . Find ( "Canvas" ) ; Transform Bottom = canvas . Find ( "Bottom" ) ; Transform tip = canvas . Find ( "Tip" ) ; layers . Add ( Layer . Bottom , Bottom ) ; layers . Add ( Layer . Tip , tip ) ; for ( int i = 0 ; i < 10 ; i ++ ) { Transform Layer = canvas . Find ( "Layer" + i ) ; layers . Add ( ( Layer ) ( i + 1 ) , Layer ) ; } } //打开面板 public static void Open < T > ( params object [ ] para ) where T : BasePanel { //已经打开 string name = typeof ( T ) . ToString ( ) ; if ( panels . ContainsKey ( name ) ) { return ; } //组件 BasePanel panel = root . gameObject . AddComponent < T > ( ) ; panel . OnInit ( ) ; panel . Init ( ) ; //父容器 Transform layer = layers [ panel . layer ] ; panel . skin . transform . SetParent ( layer , false ) ; //列表 panels . Add ( name , panel ) ; //OnShow panel . OnShow ( para ) ; panel . OpenAnimation ( ) ; } //关闭面板 public static void Close ( string name ) { BasePanel panel = panels [ name ] ; //没有打开 if ( panel == null ) { return ; } panel . CloseAnimation ( ) ; } }
例子面板TipPanel.cs
    
using System . Collections . Generic ; using UnityEngine ; using UnityEngine . UI ; public class TipPanel : BasePanel { //提示文本 private Text text ; //确定按钮 private Button okBtn ; //初始化 public override void OnInit ( ) { skinPath = "Panel/TipPanel" ; layer = PanelManager . Layer . Tip ; } //显示 public override void OnShow ( params object [ ] args ) { //寻找组件 text = skin . transform . Find ( "Text" ) . GetComponent < Text > ( ) ; okBtn = skin . transform . Find ( "OkBtn" ) . GetComponent < Button > ( ) ; //监听 okBtn . onClick . AddListener ( OnOkClick ) ; //提示语 if ( args . Length == 1 ) { text . text = ( string ) args [ 0 ] ; } } //关闭后 public override void OnClosed ( ) { } //当按下确定按钮 public void OnOkClick ( ) { Close ( ) ; } }
面板我们可以通过在子类中重写 ---面板的生命周期---中的 OnShowing() OnShowed() OnClosing() OnClosed() 方法来实现面板动画开始前和后要实现的方法
我们可以可以通过在子类中重写 OpenAnimation() CloseAnimation() 里面的动画来单独实现某个面板的打开关闭动画 也可以通过修改父类BasePanel的 OpenAnimation() CloseAnimation() 来批量修改面板的打开关闭动画 这里的动画插件我们使用dotween 不会的同学可以去泰课在线找教程学一学
最重要的2个方法 Open<T>(params object[] para)//打开T类型的面板 para是任意数量的参数 Close(string name)/关闭T类型名字的面板 通过单例类 PanelManager.xxx调用就行了
###注意:调用PanelManager的方法前请调用一次PanelManager.Init()进行PanelManager的初始化
###UIroot请进行这样的布局如果您看不懂代码的话
###UI预制体建议放在这个文件夹下
以下是我的例子代码拿过就可以用,也可以用来参考。 https://github.com/yicong1406410220/UIManagerExample
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值