Unity 3D物体点击交互

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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容