美文网首页
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