身负灵石行天下,冲关断喝辨正邪;|

青衫磊落长歌行

园龄:4年2个月粉丝:2关注:1

2022-01-15 11:06阅读: 87评论: 0推荐: 0

Unity自定义Button

2022.10.27更新:

该代码中包含以下几个事件:保持按下事件,与其他事件共存

双击事件会先触发单击,这个问题已经解决,抱歉拖了这么久才完善.

并且新按钮命名为:ButtonPro

/* 
 * ================================================
 * Describe:      This script is used to custom UGUI`s button. 
 * Author:        Xiaohei.Wang(Wenhao)
 * CreationTime:  2022-10-26 16:43:48
 * ModifyAuthor:  Xiaohei.Wang(Wenhao)
 * ModifyTime:    2022-10-26 16:43:48
 * ScriptVersion: 0.1
 * ===============================================
*/

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.Serialization;
using UnityEngine.UI;

namespace GameFramework.UI
{
    [RequireComponent(typeof(Image))]
    [RequireComponent(typeof(CanvasRenderer))]
    public class ButtonPro : Selectable, ISubmitHandler
    {
        protected ButtonPro() { }

        [Serializable]
        public class ButtonClickedEvent : UnityEvent { }

        [FormerlySerializedAs("onClick")]
        [SerializeField]
        private ButtonClickedEvent m_OnClick = new ButtonClickedEvent();

        [FormerlySerializedAs("onLongPress")]
        [SerializeField]
        private ButtonClickedEvent m_onLongPress = new ButtonClickedEvent();

        [FormerlySerializedAs("onDoubleClick")]
        [SerializeField]
        private ButtonClickedEvent m_onDoubleClick = new ButtonClickedEvent();

        [FormerlySerializedAs("onKeepPress")]
        [SerializeField]
        private ButtonClickedEvent m_onKeepPress = new ButtonClickedEvent();

        public ButtonClickedEvent onClick
        {
            get { return m_OnClick; }
        }
        public ButtonClickedEvent onDoubleClick
        {
            get { return m_onDoubleClick; }
        }
        public ButtonClickedEvent onLongPress
        {
            get { return m_onLongPress; }
        }
        public ButtonClickedEvent onKeepPress
        {
            get { return m_onKeepPress; }
        }

        private float m_longPressIntervalTime = 600.0f;
        private float m_doubleClcikIntervalTime = 170.0f;
        
        private float m_clickCount = 0;
        private bool m_onHoldDown = false;
        private bool m_isKeepPress = false;
        private bool m_onEventTrigger = false;
        private double m_clickIntervalTime = 0;
        private DateTime m_clickStartTime;

        private void OnAnyEventTrigger()
        {
            m_clickCount = 0;
            m_onEventTrigger = true;
            m_clickStartTime = default;
        }

        private void Press()
        {
            if (!IsActive() || !IsInteractable())
                return;

            UISystemProfilerApi.AddMarker("Button.onClick", this);
            m_OnClick.Invoke();
        }

        private void Update()
        {
            if (!this.interactable) return;
            m_clickIntervalTime = (DateTime.Now - m_clickStartTime).TotalMilliseconds;

            if (!m_onHoldDown && 0 != m_clickCount)
            {
                if (m_clickIntervalTime >= m_doubleClcikIntervalTime && m_clickIntervalTime < m_longPressIntervalTime)
                {
                    if (m_clickCount == 2)
                        m_onDoubleClick?.Invoke();
                    else
                        onClick?.Invoke();
                    OnAnyEventTrigger();
                }
            }

            if (m_onHoldDown && !m_onEventTrigger)
            {
                if (m_clickIntervalTime >= m_longPressIntervalTime)
                {
                    m_onHoldDown = false;
                    OnAnyEventTrigger();
                    m_onLongPress?.Invoke();
                }
            }

            if (m_isKeepPress) onKeepPress?.Invoke();
        }

        public override void OnPointerDown(PointerEventData eventData)
        {
            m_onHoldDown = true;
            m_isKeepPress = true;
            m_onEventTrigger = false;
            m_clickStartTime = DateTime.Now;

            base.OnPointerDown(eventData);
        }

        public override void OnPointerUp(PointerEventData eventData)
        {
            if (m_onEventTrigger)
                return;

            m_clickCount++;
            if (m_clickCount % 3 == 0)
            {
                onClick?.Invoke();
                OnAnyEventTrigger();
                return;
            }
            else
            {
                m_onHoldDown = false;
                m_isKeepPress = false;
            }

            base.OnPointerUp(eventData);
        }

        public override void OnPointerExit(PointerEventData eventData)
        {
            m_onHoldDown = false;
            m_isKeepPress = false;

            base.OnPointerExit(eventData);
        }

        public virtual void OnSubmit(BaseEventData eventData)
        {
            Press();

            if (!IsActive() || !IsInteractable())
                return;

            DoStateTransition(SelectionState.Pressed, false);
            StartCoroutine(OnFinishSubmit());
        }

        private IEnumerator OnFinishSubmit()
        {
            var fadeTime = colors.fadeDuration;
            var elapsedTime = 0f;

            while (elapsedTime < fadeTime)
            {
                elapsedTime += Time.unscaledDeltaTime;
                yield return null;
            }

            DoStateTransition(currentSelectionState, false);
        }
    }
}

2022.01.15的内容:

该代码中包含以下几个事件:其中按着事件,与其他事件共存双击事件会先触发单击

  • onClick                         单击
  • onDoubleClick             双击
  • onLongPress               长按
  • onKeepPress               按着

 

 大家可以根据自己的需求来使用,也可以进行拓展,可能小黑的代码水平不高,但是希望能帮助到大家,如果你们拓展了告诉小黑一下,小黑会加到博客中来,并且标明是谁提供。

更新:

        2022.01.17:增加面板属性Interactable的作用。

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.Serialization;
using UnityEngine.UI;

namespace CustomTools
{
    /*
     * Introduction:Custom UGUI`s button
     * Creator:Xiaohei Wang
     */
    [RequireComponent(typeof(Image))]
    [RequireComponent(typeof(CanvasRenderer))]
    public class CustomButton : Selectable, IPointerClickHandler, ISubmitHandler
    {
        protected CustomButton() { }

        [Serializable]
        public class ButtonClickedEvent : UnityEvent { }

        [FormerlySerializedAs("onClick")]
        [SerializeField]
        private ButtonClickedEvent m_OnClick = new ButtonClickedEvent();

        [FormerlySerializedAs("onLongPress")]
        [SerializeField]
        private ButtonClickedEvent m_onLongPress = new ButtonClickedEvent();

        [FormerlySerializedAs("onDoubleClick")]
        [SerializeField]
        private ButtonClickedEvent m_onDoubleClick = new ButtonClickedEvent();

        [FormerlySerializedAs("onKeepPress")]
        [SerializeField]
        private ButtonClickedEvent m_onKeepPress = new ButtonClickedEvent();

        public ButtonClickedEvent onClick
        {
            get { return m_OnClick; }
        }
        public ButtonClickedEvent onDoubleClick
        {
            get { return m_onDoubleClick; }
        }
        public ButtonClickedEvent onLongPress
        {
            get { return m_onLongPress; }
        }
        public ButtonClickedEvent onKeepPress
        {
            get { return m_onKeepPress; }
        }

        private bool m_isPress = false;
        private bool m_longPress = false;
        private bool m_isKeepPress = false;
        private DateTime m_currentStartTime;


        private void Press()
        {
            if (!IsActive() || !IsInteractable())
                return;

            UISystemProfilerApi.AddMarker("Button.onClick", this);
            m_OnClick.Invoke();
        }

        private void Update()
        {
            if (!this.interactable) return;
            CheckForLongPress();

            if (m_isKeepPress) onKeepPress?.Invoke();
        }

        private void CheckForLongPress()
        {
            if (m_isPress && !m_longPress)
            {
                if ((DateTime.Now - m_currentStartTime).TotalMilliseconds >= 600)
                {
                    m_isPress = false;
                    m_longPress = true;
                    m_onLongPress?.Invoke();
                }
            }
        }

        public override void OnPointerDown(PointerEventData eventData)
        {
            m_isPress = true;
            m_longPress = false;
            m_isKeepPress = true;
            m_currentStartTime = DateTime.Now;

            base.OnPointerDown(eventData);
        }

        public override void OnPointerUp(PointerEventData eventData)
        {
            m_isPress = false;
            m_isKeepPress = false;

            base.OnPointerUp(eventData);
        }

        public override void OnPointerExit(PointerEventData eventData)
        {
            m_isPress = false;
            m_isKeepPress = false;

            base.OnPointerExit(eventData);
        }

        public virtual void OnPointerClick(PointerEventData eventData)
        {
            if (this.interactable && !m_longPress)
            {
                if (eventData.clickCount == 2)
                    m_onDoubleClick?.Invoke();
                else if (eventData.clickCount == 1)
                    onClick?.Invoke();
            }
        }

        public virtual void OnSubmit(BaseEventData eventData)
        {
            Press();

            if (!IsActive() || !IsInteractable())
                return;

            DoStateTransition(SelectionState.Pressed, false);
            StartCoroutine(OnFinishSubmit());
        }

        private IEnumerator OnFinishSubmit()
        {
            var fadeTime = colors.fadeDuration;
            var elapsedTime = 0f;

            while (elapsedTime < fadeTime)
            {
                elapsedTime += Time.unscaledDeltaTime;
                yield return null;
            }

            DoStateTransition(currentSelectionState, false);
        }
    }
}

希望大家:点赞,留言,关注咯~    

😘😘😘😘

唠家常

  • 小黑的今日分享结束啦,小伙伴们你们get到了么,你们有没有更好的办法呢,可以评论区留言分享,也可以加小黑的QQ:841298494,大家一起进步

今日无推荐

posted @   青衫磊落长歌行  阅读(87)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起