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,以尽可能的更新值数据,大致就酱紫(表达能力有限见谅~)