Unity自定义Button

2023.02.13更新:

新增右键单击属行,也开放了拓展内容,使用者可以随意编辑。

删除部分无用代码,让代码更简洁。

代码还是在下方

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:    2023-02-13 15:59:18
 * ScriptVersion: 0.1
 * ===============================================
*/

using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.Serialization;
using UnityEngine.UI;
using static UnityEngine.EventSystems.PointerEventData;

namespace EasyFramework.UI
{
    [AddComponentMenu("UI/Button Pro", 101)]
    [RequireComponent(typeof(Image))]
    [RequireComponent(typeof(CanvasRenderer))]
    public class ButtonPro : Selectable
    {
        protected ButtonPro() { }

        [Serializable]
        public class ButtonClickedEvent : UnityEvent { }

        [FormerlySerializedAs("onClick0")]
        [SerializeField]
        private ButtonClickedEvent m_OnClick0 = new ButtonClickedEvent();

        [FormerlySerializedAs("onClick1")]
        [SerializeField]
        private ButtonClickedEvent m_OnClick1 = new ButtonClickedEvent();

        [FormerlySerializedAs("onLongPress0")]
        [SerializeField]
        private ButtonClickedEvent m_onLongPress0 = new ButtonClickedEvent();

        [FormerlySerializedAs("onDoubleClick0")]
        [SerializeField]
        private ButtonClickedEvent m_onDoubleClick0 = new ButtonClickedEvent();

        [FormerlySerializedAs("onKeepPress0")]
        [SerializeField]
        private ButtonClickedEvent m_onKeepPress0 = new ButtonClickedEvent();

        public ButtonClickedEvent onClick0
        {
            get { return m_OnClick0; }
        }
        public ButtonClickedEvent onClick1
        {
            get { return m_OnClick1; }
        }
        public ButtonClickedEvent onDoubleClick0
        {
            get { return m_onDoubleClick0; }
        }
        public ButtonClickedEvent onLongPress0
        {
            get { return m_onLongPress0; }
        }
        public ButtonClickedEvent onKeepPress0
        {
            get { return m_onKeepPress0; }
        }

        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;
            Debug.LogWarning("sssssssssssssssss");
            UISystemProfilerApi.AddMarker("Button.onClick", this);
            m_OnClick0.Invoke();
        }

        private void Update()
        {
            if (!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_onDoubleClick0?.Invoke();
                    else
                        onClick0?.Invoke();
                    OnAnyEventTrigger();
                }
            }

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

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

        public override void OnPointerDown(PointerEventData eventData)
        {
            if (eventData.button == InputButton.Left)
            {
                m_onHoldDown = true;
                m_onEventTrigger = false;
                m_clickStartTime = DateTime.Now;
            }
            m_isKeepPress = true;
            base.OnPointerDown(eventData);
        }

        public override void OnPointerUp(PointerEventData eventData)
        {
            if (eventData.button == InputButton.Right)
            {
                onClick1?.Invoke();
                OnAnyEventTrigger();
            }
            else if (eventData.button == InputButton.Left && !m_onEventTrigger)
            {
                m_clickCount++;
                if (m_clickCount % 3 == 0)
                {
                    onClick0?.Invoke();
                    OnAnyEventTrigger();
                    return;
                }
                else
                {
                    m_onHoldDown = false;
                    m_isKeepPress = false;
                }
            }
            m_isKeepPress = false;

            base.OnPointerUp(eventData);
        }

        public override void OnPointerExit(PointerEventData eventData)
        {
            if (eventData.button == InputButton.Left)
            {
                m_onHoldDown = false;
            }
            m_isKeepPress = false;

            base.OnPointerExit(eventData);
        }
    }
}

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,大家一起进步

今日无推荐

  • 10
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青衫磊落长歌行

觉得小黑这篇文章不赖,打赏哟~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值