工作中遇到一个问题,客户说有时候会误触到按钮,操作不方便,希望将按钮改为双击生效。既然客户有要求,那就要完成,实现起来也非常简单。
最偷懒的方法是将原来Button中Button组件去除,然后自己写一个双击脚本挂上去就行。但这样复用起来比较麻烦,就顺便研究了一下Unity如何制作自定义控件。
任务:如何制作一个自定义的双击按钮。
如何实现:1、如何实现添加自定义控件
2、如何实现双击功能
添加自定义控件很简单,UGUI是开源的,只要拷贝相关的源代码(UGUI源码下载),然后依葫芦画瓢照着写一个就可以了。UGUI中为了管理方便,分为Control和MenuOption,所以我们新建两个类,也按照UGUI的要求实现。
代码如下:
public static class CustomUIDefaultControl {
#region UGUI源码
#endregion
public static GameObject CreateDoubleClickButton(Resources resources)
{
GameObject dcButton = DefaultControls.CreateButton(convertToDefaultResources(resources));
dcButton.name = "DoubleClickButton";
dcButton.transform.Find("Text").GetComponent<Text>().text = "DoubleClickButton";
Object.DestroyImmediate(dcButton.GetComponent<Button>());
dcButton.AddComponent<DoubleClickButton>();
return dcButton;
}
public static class CustomUIMenuOptions {
#region UGUI源码
#endregion
[MenuItem("GameObject/UI/CustomUI/DoubleClickButton")]
public static void AddDoubleClickButton(MenuCommand menuCommand)
{
GameObject dcButton = CustomUIDefaultControl.CreateDoubleClickButton(GetStandardResources());
PlaceUIElementRoot(dcButton, menuCommand);
}
}
为了简洁,此处代码不包括UGUI的源码,有需要的小伙伴可以直接在上面的链接下载。然后在Hierarchy菜单栏右键就可以添加自定义控件了。
2、实现双击功能
解决方法:通过自己写一个双击事件完成,具体代码如下:
[AddComponentMenu("UI/DoubleClickButton")]
public class DoubleClickButton : Button {
public class DoubleClickEvent : UnityEvent { }
private DoubleClickEvent onDoubleClick = new DoubleClickEvent();
public DoubleClickEvent OnDoubleClick
{
get { return onDoubleClick; }
set { onDoubleClick = value; }
}
private DateTime firstClickTime;
private DateTime secondClickTime;
private void DoubleClick()
{
if (onDoubleClick != null)
//调用所有注册的事件
onDoubleClick.Invoke();
ResetTime();
}
//重置时间
private void ResetTime()
{
firstClickTime = default(DateTime);
secondClickTime = default(DateTime);
}
public override void OnPointerDown(PointerEventData eventData)
{
base.OnPointerDown(eventData);
if (firstClickTime.Equals(default(DateTime)))
firstClickTime = DateTime.Now;
else
secondClickTime = DateTime.Now;
}
public override void OnPointerUp(PointerEventData eventData)
{
base.OnPointerUp(eventData);
//如果只按了第一下,却没有按第二下,调用协程,一段时间内重置时间
if (!firstClickTime.Equals(default(DateTime)) && secondClickTime.Equals(default(DateTime)))
StartCoroutine(TimeOverResert());
if (!firstClickTime.Equals(default(DateTime))&& !secondClickTime.Equals(default(DateTime)))
{
//时间少于0.5秒则算完成双击
if ((secondClickTime - firstClickTime).Seconds + (secondClickTime - firstClickTime).Milliseconds < 500)
DoubleClick();
else
ResetTime();
}
}
IEnumerator TimeOverResert()
{
yield return new WaitForSeconds(1);
ResetTime();
}
}
测试代码:
public class Test : MonoBehaviour {
public DoubleClickButton doubleClickButton;
void Start () {
doubleClickButton.OnDoubleClick.AddListener(() => { print("触发了双击事件"); });
}
}
实际演示效果:
案例Demo