Unity实现判定UGUI的Button是否被点击

Unity中在判断某个Button是否被点击的时候,就需要在这个Button的点击事件上加监听,这样下来一通操作很麻烦,为此博主封装了一个针对于Button的拓展方法,可直接判定Button是否被点击,目的是提高效率,但不保证兼容各种复杂项目哦。首先介绍如何使用,末尾简单概述一下实现思路。


实现代码:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class UGUIButtonChecker : MonoBehaviour
{
    void Update()
    {
        List<int> btns = ButtonExpand.btns;
        if (ButtonExpand.btns.Count != 0)
        {
            foreach (var item in btns)
            {
                ButtonExpand.btnDc[item] = false;
            }
            btns.Clear();
        }
    }
}

// Button 拓展类
public static class ButtonExpand
{
    public static Dictionary<int, bool> btnDc = new Dictionary<int, bool>();//字典(键:按钮的ID,值:按钮是否被点击)
    public static List<int> btns = new List<int>();
    static GameObject obj;//常驻



    /// <summary>
    /// 拓展方法:判断Button是否被点击
    /// </summary>
    public static bool isClick(this Button btn)
    {
        if (btn == null)
            return false;

        if (obj == null)
        {
            UGUIButtonChecker o = Object.FindObjectOfType<UGUIButtonChecker>();
            if (o == null)
            {
                (obj = new GameObject("UGUI Button Checker")).AddComponent<UGUIButtonChecker>();
            }
            else
            {
                obj = o.gameObject;
            }
            Object.DontDestroyOnLoad(obj);
        }
        int instanID = btn.GetInstanceID();

        if (btnDc.ContainsKey(instanID) == false)
        {
            btnDc.Add(instanID, false);

            btn.onClick.AddListener(() =>
            {
                btnDc[instanID] = true;
            });
        }

        bool isCli = btnDc[instanID];
        if (isCli)
        {
            if (btns.Contains(instanID) == false)
                btns.Add(instanID);
        }
        return isCli;
    }

    /// <summary>
    /// 拓展方法:如果Button调用“RemoveAllListeners”,之后需调用一遍此方法,以免出现未知错误!
    /// </summary>
    public static void RemoveAllListenersLater(this Button btn)
    {
        //按钮点击事件的监听被移除了,这个按钮也需要从字典中移除了
        if (btnDc.ContainsKey(btn.GetInstanceID()))
        {
            btnDc.Remove(btn.GetInstanceID());
        }
    }
}

使用方法:

在Unity中创建一个名为 “UGUIButtonChecker” 的脚本文件,把上面的代码粘贴进去即可。

然后在button组件中,就能发现多了一个isClick()方法,建议在此方法放在Update中来实时判定。

下面是一个使用案例(Unity 2021.3.23 f1c1):

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class NewBehaviourScript : MonoBehaviour
{
    [SerializeField] private Button btn1;
    [SerializeField] private Button btn2;
    [SerializeField] private TextMeshProUGUI text;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (btn1.isClick())
        {
            text.text = "Btn1 is Clicked";
        }
        else if (btn2.isClick())
        {
            text.text = "Btn2 is Clicked";
        }

    }
}


实现思路:

维护一个字典,以 “按钮(ID)” 为键,以 “是否被点击(布尔值)” 为值,在调用Button对象的isClick方法时,实际上是在字典查询此按钮(ID)的值(布尔值),值为true时,代表了被点击了。同时当字典中存被点击的值(布尔)为true时,在下一帧就将其值(布尔值)为false,以尽可能的更新值数据,大致就酱紫(表达能力有限见谅~)

猜你喜欢

转载自blog.csdn.net/njiyue/article/details/136353715