美文网首页
Unity 3D物体点击交互

Unity 3D物体点击交互

作者: 114105lijia | 来源:发表于2022-08-09 19:16 被阅读0次

1、在3D物体表面添加一个Quad
2、给Quad添加一个材质
3、添加Box Collider
4、设置自定义Layer层(如果不设置,移动端会有点击事件冲突)
5、给摄像机添加Physics Raycaster组件
6、添加EventSystem
7、添加测试脚本,挂在Quad上

image.png
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

相关文章

网友评论

      本文标题:Unity 3D物体点击交互

      本文链接:https://www.haomeiwen.com/subject/yggnwrtx.html