Unity实现按钮Button多功能(长按,双击)。
今天在做游戏的时候突发奇想,为什么Unity只有单击捏?例如:以前的iPhone的Home键双击就是任务栏,单击就是回到主界面。那么在Unity应该也能实现吧(好像没什么关联。。。),毕竟现在很多游戏都存在双击的功能。于是我去网络上查找并学习了下,把心得写在这,方便大家可以参考参考。
思路
既然我们需要手动写一个按钮,那么就需要去监听GameObject的点击事件。这里我设置了几个Public变量,并且实现了几个鼠标事件的接口,具体的代码如下:
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
public class ButtonMySelf : MonoBehaviour,IPointerDownHandler,IPointerUpHandler
{
#region Public Variables
public float pressDurationTime = 1;
public float doubleClickIntervalTime = 0.5f;
public UnityEvent onDoubleClick;
public UnityEvent onPress;
public UnityEvent onClick;
#endregion
#region Private Variables
private bool isDown = false;
private bool isPress = false;
private float downTime = 0;
private float clickIntervalTime = 0;
private int clickTimes = 0;
#endregion
#region Unity Methods
// Update is called once per frame
void Update()
{
if (isDown)
{
if (isPress) return;
downTime += Time.deltaTime;
if (downTime > pressDurationTime)
{
isPress = true;
onPress.Invoke();
downTime = 0;
}
}
if (clickTimes >= 1)
{
clickIntervalTime += Time.deltaTime;
if (clickIntervalTime >= doubleClickIntervalTime)
{
if (clickTimes >= 2)
{
onDoubleClick.Invoke();
}
else
{
onClick.Invoke();
}
clickTimes = 0;
clickIntervalTime = 0;
}
}
}
#endregion
#region Public Methods
public void OnPointerDown(PointerEventData eventData)
{
isDown = true;
}
public void OnPointerUp(PointerEventData eventData)
{
isDown = false;
if (!isPress) clickTimes += 1;
isPress = false;
}
#endregion
}
这里就跟大家说说思路吧,首先当点击的时候我们会把isDown设置为true,然后在每一帧进行检测是否按下了鼠标(也就是监听isDown)。如果鼠标点击下去了那么我们会先进行判断是否为按压,按压的话取消这一帧鼠标的判断(因为当你按压的时候isDown也是一直为true)。如果不是按压事件,那么就会开始按秒计时,当你的按压时间大于了pressDurationTime,就会把isPress设置为真,并且调用按压事件的函数,最后把按压计时归零!!!
下一个if的判断使用来判断双击的,在OnPoinerUp这个函数里面,会对你的点击次数进行计数(按下并放开记为一次),当然如果你是按压状态那么就算你放开了他也不会进行计数这个动作。当你点击一次以后他就会开始if里面的判断啦,也就是开始第一次点击后的计时,当你第一次点击后的计时大于等于你规定的双击时间doubleClickIntervalTime时候就会进行判断:在这个时间段里面你是不是又点击了一次(当然你要是在规定时间里面点击了一百次,那。。。也算你双击啦)。如果又点击了一次那么就会执行双击的事件,要不然就执行单击事件。
然后把它挂在你的GameObject下。
最后
然后就是写个自己想要双击实现的脚本然后挂上去就可以用啦!!!
我的代码是这样的:
using UnityEngine;
using UnityEngine.UI;
public class ButtonTest : MonoBehaviour
{
#region Private Variables
[SerializeField] private GameObject showTips = null;
[SerializeField] private float DuringTPOT = 2f;
private float timeCount = 0;
#endregion
#region Unity Methods
// Start is called before the first frame update
void Start()
{
ButtonMySelf btn = GetComponent<ButtonMySelf>();
btn.onClick.AddListener(Click);
btn.onPress.AddListener(Press);
btn.onDoubleClick.AddListener(DoubleCick);
}
// Update is called once per frame
void Update()
{
if (timeCount >= 0 && showTips.activeSelf == true && showTips != null)
{
timeCount += Time.deltaTime;
if (timeCount >= DuringTPOT) showTips.SetActive(false);
}
}
#endregion
#region Private Methods
private void DoubleCick()
{
if (showTips == null)
{
Debug.LogWarning("Losting Text of GameObject,Please Adding.");
return;
}
showTips.GetComponent<Text>().text = "开启免费奖励模式";
showTips.SetActive(true);
timeCount = 0;
}
private void Press()
{
if (showTips == null)
{
Debug.LogWarning("Losting Text of GameObject,Please Adding.");
return;
}
showTips.GetComponent<Text>().text = "关闭了免费奖励模式";
showTips.SetActive(true);
timeCount = 0;
}
private void Click()
{
if (showTips == null)
{
Debug.LogWarning("Losting Text of GameObject,Please Adding.");
return;
}
showTips.GetComponent<Text>().text = "发现了隐藏按钮";
showTips.SetActive(true);
timeCount = 0;
}
#endregion
}
上面是我用来做游戏Debug的。。。嘻嘻
我的代码写的不是很好,我也是模仿别人写的。
刚刚接触代码和做游戏一个月,写的不好的地方希望能多多包容。当然也可以指出错误,互相学习。^^
最后的最后,附上我参考别人的链接。毕竟也是模仿别人写的(大部分都是),我只是把他的代码语言化了一点。(有一些接口我没用到,具体的可以看看原链接)
链接:https://blog.csdn.net/shuai1210/article/details/83866811