UGUI自动化–QButton&QToggleButton&QToggleButtonGroup

22 篇文章 1 订阅
21 篇文章 0 订阅

UGUI自动化–QButton&QToggleButton&QToggleButtonGroup

本系列来自https://github.com/onelei/Lemon/tree/master/Assets/QGUI 今天接着介绍UGUI自动化中的Button和ToggleButton控件,相信读了前几篇文章的渐渐理解了设计思路。QButton继承自UGUI的Button组件,QToggleButton是自己设计的组件和UGUI的ToggleButton功能一样但是增加了回调函数的代码设置。同样的QToggleButtonGroup组件也是自己设计用来实现动态设置选中了某一个ToggleButton的功能以及选中之后的回调函数。说到这里可能会比较疑惑,接下来详细介绍如何使用。

QButton

在这里插入图片描述

QButton组件比较简单,就是针对UGUI的Button按钮的封装。同时挂上没有Overdraw的QImageBox组件(QImageBox可以翻阅之前的文章有介绍)。

QButton组件

新建一个QButton.cs代码如下

/**
*   Author:onelei
*   Copyright © 2019 - 2020 ONELEI. All Rights Reserved
*/
using UnityEngine;
using UnityEngine.UI;

namespace Lemon.UI
{
    [AddComponentMenu("UI/QButton")]
    public class QButton : Button
    {
        [HideInInspector]
        public bool bInit = false;

        private GameObject _CacheGameObject = null;
        public GameObject CacheGameObject { get { if (_CacheGameObject == null) { _CacheGameObject = gameObject; } return _CacheGameObject; } }

        private Transform _CacheTransform = null;
        public Transform CacheTransform { get { if (_CacheTransform == null) { _CacheTransform = transform; } return _CacheTransform; } }
    }
}

接着我们新建一个QButtonEditor.cs的脚本,将其放入Editor文件夹下。代码如下

/**
*   Author:onelei
*   Copyright © 2019 - 2020 ONELEI. All Rights Reserved
*/
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;

namespace Lemon.UI
{
    [RequireComponent(typeof(QImageBox))]
    [CustomEditor(typeof(QButton), true)]
    public class QButtonEditor : UnityEditor.UI.ButtonEditor
    {
        [MenuItem("GameObject/UI/QButton", false, UtilEditor.Priority_QButton)]
        public static QButton AddComponent()
        {
            QImageBox image = UtilEditor.ExtensionComponentWhenCreate<QImageBox>(typeof(QButton).Name.ToString());
            QButton component = Util.GetOrAddCompoment<QButton>(image.gameObject);
            //设置默认值
            SetDefaultValue(component);
            return component;
        }

        QButton component;
        public override void OnInspectorGUI()
        {
            component = (QButton)target;
            base.OnInspectorGUI();
            if (!component.bInit)
            {
                component.bInit = true;
                SetDefaultValue(component);
            }
        }

        private static void SetDefaultValue(QButton component)
        {
            if (component == null)
                return;
            if (component.targetGraphic != null)
                component.targetGraphic.raycastTarget = true;
        } 
    }
}

同样我们通过SetDefaultValue函数来重写Button组件里面的参数。这个比较简单,但是接下来我们看看QToggleButton组件是如何设计的。

QToggleButton

在这里插入图片描述

QToggleButton组件顾名思义就是用于按钮的切换。比如我们遇到的音量的on/off开关。QToggleButton组件挂在最上层,同时挂上没有Overdraw的QImageBox组件(QImageBox可以翻阅之前的文章有介绍)。箭头所指的Normal和Choose按钮就是用来切换显示使用的,既然有了切换显示功能,当然还需要有切换之后的回调函数的设置功能,详情如下。

QToggleButton组件

新建一个QToggleButton.cs代码如下

/**
*   Author:onelei
*   Copyright © 2019 - 2020 ONELEI. All Rights Reserved
*/
using UnityEngine;
using UnityEngine.UI;
using System;

namespace Lemon.UI
{
    [AddComponentMenu("UI/QToggleButton")]
    public class QToggleButton : QButton
    {
        public GameObject Normal;
        public GameObject Choose;

        //Group
        private int index = -1;
        private int curIndex = -1;
        private Action<int, int> OnGroupAction = null;
        private bool bGroup = false;
        //Toggle
        private Action<bool> OnToggleAction;

        private bool bChoose = false;

        public void SetData(bool bChoose, Action<bool> OnToggleAction, bool doAction = false)
        {
            this.bGroup = false;
            this.OnToggleAction = OnToggleAction;
            SetChoose(bChoose);
            if (doAction)
            {
                OnToggleAction(bChoose);
            }
            this.onClick.RemoveListener(ClickEvent);
            this.onClick.AddListener(ClickEvent);
        }

        public void SetGroupData(int index, int curIndex, Action<int, int> OnGroupAction)
        {
            this.bGroup = true;
            this.index = index;
            this.curIndex = curIndex;
            this.OnGroupAction = OnGroupAction;

            SetChoose(curIndex == index);
            this.onClick.RemoveListener(ClickEvent);
            this.onClick.AddListener(ClickEvent);
        }

        public void SetChoose(int _index)
        {
            this.curIndex = _index;
            SetChoose(curIndex == index);
        }

        public void SetChoose(bool bChoose)
        {
            this.bChoose = bChoose;

            if (Normal != null)
            {
                Normal.SetActive(!bChoose);
            }
            if (Choose != null)
            {
                Choose.SetActive(bChoose);
            }
        }

        private void ClickEvent()
        {
            if (bGroup)
            {
                if (index == curIndex)
                    return;
                if (OnGroupAction != null)
                {
                    OnGroupAction(curIndex, index);
                }
            }
            else
            {
                SetChoose(!bChoose);
                if (OnToggleAction != null)
                {
                    OnToggleAction(bChoose);
                }
                QLog.LogEditor("当前bChoose: " + bChoose);
            }
        }

#if UNITY_EDITOR
        [ContextMenu("SetToggleEditor")]
        public void SetToggleEditor(bool bChoose = false)
        {
            this.bChoose = bChoose;
            SetData(bChoose, null);
        }
#endif
    }
}

脚本里面有一个函数SetData

public void SetData(bool bChoose, Action<bool> OnToggleAction, bool doAction = false)
        {
            this.bGroup = false;
            this.OnToggleAction = OnToggleAction;
            SetChoose(bChoose);
            if (doAction)
            {
                OnToggleAction(bChoose);
            }
            this.onClick.RemoveListener(ClickEvent);
            this.onClick.AddListener(ClickEvent);
        }

参数1:bChoose为true的时候表明切换为Choose状态,为false表明切换为Normal状态

参数2:OnToggleAction是传入的回调函数。当玩家点击了QToggleButton的时候会自动触发。里面的bool参数也会设置上。true表明Choose状态,false表明Normal状态。

参数3:doAction表明当前是否执行回调函数。默认为false,表明当前不执行回调函数。

接着我们新建一个QToggleButtonEditor.cs的脚本,将其放入Editor文件夹下。代码如下

/**
*   Author:onelei
*   Copyright © 2019 - 2020 ONELEI. All Rights Reserved
*/
using UnityEditor;
using UnityEngine.UI;
using UnityEngine;

namespace Lemon.UI
{
    [RequireComponent(typeof(QImageBox))]
    [CustomEditor(typeof(QToggleButton), true)]
    public class QToggleButtonEditor : QButtonEditor
    {
        [MenuItem("GameObject/UI/QToggleButton", false, UtilEditor.Priority_QToggleButton)]
        public static new QToggleButton AddComponent()
        {
            QImageBox image = QImageBoxEditor.AddComponent();
            image.raycastTarget = true;

            QToggleButton component = Util.GetOrAddCompoment<QToggleButton>(image.CacheGameObject);
            component.name = typeof(QToggleButton).Name.ToString();
            //设置默认值
            SetDefaultValue(component);
            return component;
        }

        QToggleButton component;
        public override void OnInspectorGUI()
        {
            component = (QToggleButton)target;
            component.Normal = (GameObject)EditorGUILayout.ObjectField("Normal", component.Normal, typeof(GameObject), true);
            component.Choose = (GameObject)EditorGUILayout.ObjectField("Choose", component.Choose, typeof(GameObject), true);

            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Normal"))
            {
                component.SetToggleEditor();
            }
            if (GUILayout.Button("Choose"))
            {
                component.SetToggleEditor(true);
            }
            GUILayout.EndHorizontal();

            //base.OnInspectorGUI();
            if (!component.bInit)
            {
                component.bInit = true;
                SetDefaultValue(component);
            }
        }

        private static void SetDefaultValue(QToggleButton component)
        {
            if (component == null)
                return;
            if (component.targetGraphic != null)
                component.targetGraphic.raycastTarget = true;
            component.SetToggleEditor();
        }
    }
}

QToggleButton是用来控制一个按钮的切换状态,但是当我们需要多个按钮互斥显示的时候,类似于UGUI的ToggleGroup,该如何处理呢?接着往下看。

QToggleButtonGroup

在这里插入图片描述

我们通过一个index表明当前是选中了第几个按钮,图中的按钮Choose表明立刻设置选中。编辑器下面index可以通过Choose按钮动态设置。

QToggleButtonGroup组件

新建一个QToggleButtonGroup.cs代码如下

/**
*   Author:onelei
*   Copyright © 2019 - 2020 ONELEI. All Rights Reserved
*/
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Collections.Generic;

namespace Lemon.UI
{
    [AddComponentMenu("UI/QToggleButtonGroup")]
    public class QToggleButtonGroup : BaseMonoClass
    {
        [SerializeField]
        public List<QToggleButton> list = new List<QToggleButton>();

        //内部变量
        private int pre;
        private int cur;
        private Action<int, int> OnGroupAction;

        public void SetData(int index, Action<int, int> OnGroupAction, bool doAction = false)
        {
            this.pre = -1;
            this.cur = -1;

            this.cur = index;
            this.OnGroupAction = OnGroupAction;

            int length = list.Count;
            for (int i = 0; i < length; i++)
            {
                QToggleButton toggleButton = list[i];
                toggleButton.SetGroupData(i, index, OnGroup);
            }

            if (doAction)
            {
                OnGroup(pre, cur);
            }
        }

        public void OnGroup(int pre, int cur)
        {
            QLog.LogEditor(StringPool.Format("点击pre = {0}, cur = {1}.", pre, cur));

            //设置所有组件的显示隐藏
            int length = list.Count;
            for (int i = 0; i < length; i++)
            {
                QToggleButton toggleButton = list[i];
                toggleButton.SetChoose(cur);
            }

            //设置组件的回调函数
            if (OnGroupAction != null)
            {
                OnGroupAction(pre, cur);
            }
        }

#if UNITY_EDITOR
        [ContextMenu("SetToggleGroupEditor")]
        public void SetToggleGroupEditor(int index = 0)
        {
            SetData(index, null);
        }
#endif
    }
} 

在这里我们同样增加了SetData这样一个函数

public void SetData(int index, Action<int, int> OnGroupAction, bool doAction = false)
        {
            this.pre = -1;
            this.cur = -1;

            this.cur = index;
            this.OnGroupAction = OnGroupAction;

            int length = list.Count;
            for (int i = 0; i < length; i++)
            {
                QToggleButton toggleButton = list[i];
                toggleButton.SetGroupData(i, index, OnGroup);
            }

            if (doAction)
            {
                OnGroup(pre, cur);
            }
        }

参数1:index表明当前是选中了第几个按钮。

参数2:OnGroupAction是当玩家选中这些互斥按钮时候的回调函数。第一个int是之前选中的index,第二个int是

当前选中的index。

参数3:doAction表明当前是否执行回调函数。默认为false,表明当前不执行回调函数。

接着我们新建一个QToggleButtonGroupEditor.cs的脚本,将其放入Editor文件夹下。代码如下

/**
*   Author:onelei
*   Copyright © 2019 - 2020 ONELEI. All Rights Reserved
*/
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;

namespace Lemon.UI
{
    [CustomEditor(typeof(QToggleButtonGroup))]
    public class QToggleButtonGroupEditor : Editor
    {
        [MenuItem("GameObject/UI/QToggleButtonGroup", false, UtilEditor.Priority_QToggleButtonGroup)]
        public static QToggleButtonGroup AddComponent()
        {
            QToggleButtonGroup component = UtilEditor.ExtensionComponentWhenCreate<QToggleButtonGroup>(typeof(QToggleButtonGroup).Name.ToString());
            component.list.Clear();

            for (int i = 0; i < 2; i++)
            {
                Selection.activeObject = component;
                QToggleButton button = QToggleButtonEditor.AddComponent();
                component.list.Add(button);
            }
            Selection.activeObject = component;
            return component;
        }

        QToggleButtonGroup component;
        int index = 0; 
        public override void OnInspectorGUI()
        { 
            component = (QToggleButtonGroup)target;
            GUILayout.BeginHorizontal();
            index = EditorGUILayout.IntField("index", index);
            if (GUILayout.Button("Choose"))
            {
                component.SetToggleGroupEditor(index);
            }
            GUILayout.EndHorizontal();

            base.OnInspectorGUI();
        }
    }
} 

详细代码参见:https://github.com/onelei/Lemon/tree/master/Assets/QGUI,欢迎Star。如果本文对你有所帮助,欢迎赞赏~~~

欢迎关注微信公众号:Unity游戏开发笔记
在这里插入图片描述
QQ群:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值