TEngine UI模块

5.UI模块 - UIModule

一个游戏70%都是UI,剩下30%才是GamePlay,所以有一套简洁强大的商业化UI模块以及UI开发工作流将是项目的一大利器,能够提高至少一倍的开发效率。(配合事件模块实现MVE[Model - View - Event]事件驱动架构)
UI脚本为纯C#实现,脱离Mono的生命周期,由UIModule的帧更新驱动并管理UI的生命周期。
IUIBehaviour为UI通用行为接口、UIBase为UI基类、UIWindow为UI窗口基类,UIWidget为UI组件基类。

前期配置:

注意!!!!m_item节点为特殊节点表示是UI下的UIWidget组件,不会继续往下遍历生成UI代码。若需要这个UIWidget组件m_item的代码则在m_item右键生成这个组件的UI脚本。
Scene窗口下右键ScriptGenerator菜单下About目录有默认UI命名前缀规范。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nZIX9P1Y-1693201314593)(https://github.com/ALEXTANGXIAO/TEngine/raw/main/Books/src/3-5-1.png#from=url&id=haa6v&originHeight=587&originWidth=493&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=)]
有自定义需求可以在TEngineSetting下进行自定义。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D7YavFur-1693201314594)(https://github.com/ALEXTANGXIAO/TEngine/raw/main/Books/src/3-5-2.png#from=url&id=pRAFG&originHeight=747&originWidth=1436&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=)]

开发工作流:

1.遵守前期默认配置或者自定义配置进行UI编排
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dOeoYp5q-1693201314595)(https://github.com/ALEXTANGXIAO/TEngine/raw/main/Books/src/3-5-3.png#from=url&id=wn16J&originHeight=465&originWidth=719&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=)]
2.在UI的根节点右键ScriptGenerator生成UI代码到剪贴板上!!!(注-使用-UniTask的生成代码可以做异步事件流驱动的UI
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qck9sXgp-1693201314595)(https://github.com/ALEXTANGXIAO/TEngine/raw/main/Books/src/3-5-4.png#from=url&id=fryG9&originHeight=671&originWidth=683&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=)]
3.自行创建UI脚本到需要的目录下复制UI脚本

举例示范

// 同步打开面板
GameModule.UI.ShowUI<GameMainUI>([nullable]userData);

// 异步打开面板
GameModule.UI.ShowUIAsync<GameMainUI>([nullable]userData);

namespace GameLogic
{
    /// <summary>
    /// BattleMainUI面板
    /// <remarks>UIWindow需要以下特性,UILayer可以自行定义,fullScreen表示为全屏面板会停止和隐藏这个面板堆栈后面的面板。</remarks>
    /// </summary>
    [Window(UILayer.Bottom,fullScreen:true)]
    class BattleMainUI : UIWindow
    {
        private TouchMove m_touchView;
        
        #region 脚本工具生成的代码
        private RectTransform m_rectContainer;
        private GameObject m_itemTouch;
        private Button m_btnLeaveBattle;
        private GameObject m_goTopInfo;
        private Button m_btnPause;
        public override void ScriptGenerator()
        {
            m_rectContainer = FindChildComponent<RectTransform>("m_rectContainer");
            m_itemTouch = FindChild("m_rectContainer/m_itemTouch").gameObject;
            m_btnLeaveBattle = FindChildComponent<Button>("m_btnLeaveBattle");
            m_goTopInfo = FindChild("m_goTopInfo").gameObject;
            m_btnPause = FindChildComponent<Button>("m_goTopInfo/m_btnPause");
            m_btnLeaveBattle.onClick.AddListener(OnClickLeaveBattleBtn);
            m_btnPause.onClick.AddListener(OnClickPauseBtn);
        }
        #endregion

        #region 事件

        private void OnClickPauseBtn()
        {
            BattleSys.Instance.Pause = !BattleSys.Instance.Pause;
        }

        private void OnClickLeaveBattleBtn()
        {
            BattleSys.Instance.StopBattle(isBattleEnd:false,isWin:false);
        }
        #endregion

        //注册事件举例
        public override void RegisterEvent()
        {
            //通过AddUIEvent这样注册事件会把事件的生命周期绑定给面板,面板销毁的时候自动移除监听。
            AddUIEvent(ActorLogicEventDefined.OnMainPlayerBagDataChange, RefreshUI);
        }

        public override void BindMemberProperty()
        {
            //特殊的m_item节点的域不属于父级UIWindows,所以如注意所说需要同样创建这个UIWidget的脚本并生成代码过去。 可以如下创建或者走type、path创建。
            m_touchView = CreateWidget<TouchMove>(m_itemTouch);
        }

        ......
    }
}

namespace GameLogic
{
    /// <summary>
    /// 移动操作UIWidget。
    /// </summary>
    class TouchMove : UIWidget, IUICtrlMove
    {
        public override void BindMemberProperty()
        {
        }

        //注意Update只有在重写了此方法才会驱动这个Widget或者面板的Update。
        public override void OnUpdate()
        {
            TProfiler.BeginSample("CheckMoveTouchFinger");
            CheckMoveTouchFinger();
            TProfiler.EndSample();

            TProfiler.BeginSample("UpdateTouchMovePos");
            UpdateTouchMovePos();
            TProfiler.EndSample();

            TProfiler.BeginSample("UpdateKeyMove");
            UpdateKeyMove();
            TProfiler.EndSample();
        }
        ......
    }
}

UI进阶

UI面板需要标记UIWindowAttribute,以标识层级(可以自行定义)和是否全屏。全屏面板则会把下层面板的Visible设置为false。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V7RmvNzp-1693201314596)(https://github.com/ALEXTANGXIAO/TEngine/raw/main/Books/src/3-5-5.png#from=url&id=VxJh0&originHeight=851&originWidth=1246&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=)]

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值