1、在3D物体表面添加一个Quad
2、给Quad添加一个材质
3、添加Box Collider
4、设置自定义Layer层(如果不设置,移动端会有点击事件冲突)
5、给摄像机添加Physics Raycaster组件
6、添加EventSystem
7、添加测试脚本,挂在Quad上
using UnityEngine;
public class Test : MonoBehaviour
{
private ButtonExtension modelButtonEx;
// Start is called before the first frame update
void Start()
{
modelButtonEx = ButtonExtension.Add(transform.gameObject);
modelButtonEx.onClick.AddListener(OnPlayButtonClick);
}
public void OnPlayButtonClick()
{
Debug.Log("click");
}
}
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
public class ButtonExtension : MonoBehaviour, IPointerClickHandler, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler
{
[Header("长按时间")]
public float pressDurationTime = 0.8f;
[Header("长按是否执行一次")]
public bool responseOnceByPress = true;
[Header("双击间隔时间")]
public float doubleClickIntervalTime = 0.3f;
/// <summary>
/// 双击
/// </summary>
public UnityEvent onDoubleClick = new();
/// <summary>
/// 长按
/// </summary>
public UnityEvent onPress = new();
/// <summary>
/// 点击
/// </summary>
public UnityEvent onClick = new();
private bool isDown = false;
private bool isPress = false;
private float downTime = 0;
private float clickIntervalTime = 0;
private int clickTimes = 0;
/// <summary>
/// 添加扩展button交互事件
/// </summary>
/// <param name="go"></param>
/// <returns></returns>
public static ButtonExtension Add(GameObject go)
{
if(go == null)
{
Debug.LogError("ButtonExtension.Add 参数不能为null");
return null;
}
var btnEx = go.GetComponent<ButtonExtension>();
if(btnEx == null)
{
btnEx = go.AddComponent<ButtonExtension>();
}
return btnEx;
}
private void Start()
{
}
void Update()
{
if (isDown)
{
if (responseOnceByPress && isPress)
{
return;
}
downTime += Time.deltaTime;
if (downTime > pressDurationTime)
{
isPress = true;
onPress.Invoke();
}
}
if (clickTimes >= 1)
{
clickIntervalTime += Time.deltaTime;
if (clickIntervalTime >= doubleClickIntervalTime)
{
if (clickTimes >= 2)
{
onDoubleClick.Invoke();
}
else
{
onClick.Invoke();
}
clickTimes = 0;
clickIntervalTime = 0;
}
}
}
public void OnPointerDown(PointerEventData eventData)
{
if (OnlySingleClick())
{
return;
}
isDown = true;
downTime = 0;
}
public void OnPointerUp(PointerEventData eventData)
{
if (OnlySingleClick())
{
return;
}
isDown = false;
}
public void OnPointerExit(PointerEventData eventData)
{
isDown = false;
isPress = false;
}
public void OnPointerClick(PointerEventData eventData)
{
if (OnlySingleClick())
{
onClick?.Invoke();
return;
}
if (!isPress)
{
//onClick.Invoke();
clickTimes += 1;
}
else
{
isPress = false;
}
}
/// <summary>
/// 是否只有单击
/// </summary>
/// <returns></returns>
private bool OnlySingleClick()
{
if (onClick.GetPersistentEventCount() >= 0
&& onDoubleClick.GetPersistentEventCount() == 0
&& onPress.GetPersistentEventCount() == 0)
{
return true;
}
return false;
}
}
注意
1、Quad上面的Collider,不能与其他Trigger区域相冲突,不然点击没反应。
对应的解决方式:将Camera的Physics Raycaster组件的Event Mask设置成UI和上面第4步中的自定义layer。
image.png
网友评论