【Unityの場合】ボタンをダブルクリックして長押し

実施内容:

Unity 独自の Button コンポーネントを拡張して、元のクリック イベントに基づいてダブルクリックと長押しの効果を実現します。

Button コンポーネントを置き換え、ラジオ ボタンで現在実行されているイベントを選択します。
Button コンポーネントを置き換え、ラジオ ボタンで現在実行されているイベントを選択します。

コードの詳細な説明:

  1. クリックイベントの処理:
    • singleClickEnabled スイッチを通じてクリック イベントを有効にするかどうかを制御します。
    • OnPointerClick メソッドでは、ボタンのアクティブ化状態と対話可能状態に従ってクリック イベントを実行します。
    • Unity の Profiler API を使用してマーカーを追加し、ボタンのクリック イベント コールバックをトリガーします。
  2. ダブルクリックイベントの処理:
    • doubleClickEnabled スイッチを通じてダブルクリック イベントを有効にするかどうかを制御します。
    • OnPointerClick メソッドでは、クリック数を記録し、ダブルクリック時間のしきい値に基づいてダブルクリック イベントをトリガーするかどうかを決定します。
    • ダブルクリックが検出された場合は、プロファイラー タグを追加し、ダブルクリック イベント コールバックをトリガーし、クリック数をリセットします。
  3. 長押しイベント処理:
    • longPressEnabled スイッチを使用して、長押しイベントを有効にするかどうかを制御します。
    • OnPointerDown メソッドで、押した時間を記録し、長押し状態をマークします。
    • OnPointerUp メソッドで、長押し状態をリセットします。
    • 定期的に長押しを検出するには使用Updateメソッドを使用します。長押し時間のしきい値に達すると、長押しイベント コールバックがトリガーされます。
  4. イベントコールバック:
    • ButtonClickedEventインスペクターで構成できるタイプのイベント コールバックを使用
    • クリック、ダブルクリック、長押しのイベント コールバックを提供します。これらはインスペクターまたはコードを通じて設定できます。

完全なコードは次のとおりです。

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Serialization;
using UnityEngine.UI;

public class ButtonExtension : Button
{
    #region 单机双击相关

    public bool singleClickEnabled = true;
    public bool doubleClickEnabled = false;
    public float doubleClickTime = 0.3f;
    
    private float lastClickTime = float.NegativeInfinity;
    private int clickCount = 0;
    
    [FormerlySerializedAs("onDoubleClick")]
    [SerializeField]
    private ButtonClickedEvent doubleClickEvent = new ();
    
    public ButtonClickedEvent onDoubleClick
    {
        get => doubleClickEvent;
        set => doubleClickEvent = value;
    }

    public override void OnPointerClick(PointerEventData eventData)
    {
        if(!IsActive() && !interactable) 
            return;

        if (singleClickEnabled)
        {
            UISystemProfilerApi.AddMarker("Button.onClick", this);
            onClick?.Invoke();
            Debug.LogError("单击");   
        }

        if (doubleClickEnabled)
        {
            clickCount++;
            if (clickCount >= 2)
            {
                if (Time.realtimeSinceStartup - lastClickTime < doubleClickTime)
                {
                    UISystemProfilerApi.AddMarker("Button.onDoubleClick", this);
                    onDoubleClick?.Invoke();
                    Debug.LogError("双击");
                    lastClickTime = float.NegativeInfinity;
                    clickCount = 0;   
                }
                else
                {
                    clickCount = 1;
                    lastClickTime = Time.unscaledTime;
                }
            }
            else
            {
                lastClickTime = Time.unscaledTime;
            }
        }
    }

    #endregion

    #region 长按相关

    public bool longPressEnabled = false;

    private float lastPressTime = 0;
    
    public float minPressTime = 0.5f;

    private bool isPressing = false;
    
    private bool hasInvokedLongPress = false;

    [FormerlySerializedAs("onLongPress")]
    [SerializeField]
    private ButtonClickedEvent longPressEvent = new();
    
    public ButtonClickedEvent onLongPress
    {
        get => longPressEvent;
        set => longPressEvent = value;
    }
    
    public override void OnPointerDown(PointerEventData eventData)
    {
        base.OnPointerDown(eventData);
        if (longPressEnabled)
        {
            hasInvokedLongPress = false;
            isPressing = true;
            lastPressTime = Time.unscaledTime;   
        }
    }

    public override void OnPointerUp(PointerEventData eventData)
    {
        base.OnPointerUp(eventData);
        isPressing = false;
        hasInvokedLongPress = false;
    }

    private void Update()
    {
        DealLongPress();
    }
    
    private void DealLongPress()
    {
        if(hasInvokedLongPress) return;
        if (isPressing)
        {
            if (Time.unscaledTime - lastPressTime >= minPressTime)
            {
                UISystemProfilerApi.AddMarker("Button.onLongPress", this);
                onLongPress?.Invoke();
                hasInvokedLongPress = true;
                Debug.LogError("执行长按事件");
            }
        }
    }

    #endregion
}

新しいプロパティを [インスペクター] パネルに追加します。具体的なコードは次のとおりです。

using UnityEngine;

namespace UnityEditor.UI
{
    [CustomEditor(typeof(ButtonExtension), true)]
    [CanEditMultipleObjects]
    public class ButtonExInspector : SelectableEditor
    {
        private ButtonExtension buttonExtension;

        SerializedProperty onDoubleClickProperty;
        SerializedProperty onClickProperty;
        SerializedProperty onLongPressProperty;
        
        protected override void OnEnable()
        {
            base.OnEnable();
            onDoubleClickProperty = serializedObject.FindProperty("doubleClickEvent");
            onClickProperty = serializedObject.FindProperty("m_OnClick");
            onLongPressProperty = serializedObject.FindProperty("longPressEvent");
        }

        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();
            serializedObject.Update();
            buttonExtension = (ButtonExtension)target;
            EditorGUILayout.Space();

            buttonExtension.singleClickEnabled = EditorGUILayout.Toggle("启用单击", buttonExtension.singleClickEnabled);
            if (buttonExtension.singleClickEnabled)
            {
                buttonExtension.doubleClickEnabled = false;
                buttonExtension.longPressEnabled = false;
                EditorGUILayout.PropertyField(onClickProperty);  
            }
            
            buttonExtension.doubleClickEnabled = EditorGUILayout.Toggle("启用双击", buttonExtension.doubleClickEnabled);
            if (buttonExtension.doubleClickEnabled)
            {
                buttonExtension.doubleClickTime = EditorGUILayout.FloatField("双击间隔", buttonExtension.doubleClickTime);
                buttonExtension.singleClickEnabled = false;
                buttonExtension.longPressEnabled = false;
                EditorGUILayout.PropertyField(onDoubleClickProperty);
            }
            
            buttonExtension.longPressEnabled = EditorGUILayout.Toggle("启用长按", buttonExtension.longPressEnabled);
            if(buttonExtension.longPressEnabled)
            {
                buttonExtension.minPressTime = EditorGUILayout.FloatField("长按时间", buttonExtension.minPressTime);
                buttonExtension.singleClickEnabled = false;
                buttonExtension.doubleClickEnabled = false;
                EditorGUILayout.PropertyField(onLongPressProperty);
            }
            
            serializedObject.ApplyModifiedProperties();
            if(GUI.changed)
                EditorUtility.SetDirty(target);
        }
    }   
}


おすすめ

転載: blog.csdn.net/lel18570471704/article/details/134789342