BITKit/Packages/Runtime~/Unity/Scripts/UX/Input/UXAllowTouch.cs

125 lines
3.2 KiB
C#

using System;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.EnhancedTouch;
using UnityEngine.UIElements;
using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace BITKit.UX
{
[Serializable]
public class AllowTouchWhenPointerNotOverUI : ICondition
{
public bool OnCheck() => UXAllowTouch.Singleton.AllowTouch;
}
/*
* 当指针进入区域时启用输入
* 当指针离开区域时禁用输入,直到所有设备都没有按下,才会再次启用输入
*/
/// <summary>
/// Allow touch when pointer not over UI
/// </summary>
public class UXAllowTouch : UXElement<VisualElement>, ICondition
{
internal static UXAllowTouch Singleton { get; private set; }
public bool AllowTouch;
internal bool IsHoveringUI { get; private set; }
public bool IsTouching { get; private set; }
private int updateRequest;
private CancellationTokenSource cancellationTokenSource;
public override void OnAwake()
{
Singleton = this;
EnhancedTouchSupport.Enable();
Touch.onFingerUp += OnFingerUp;
Touch.onFingerDown += OnFingerDown;
cancellationTokenSource = new CancellationTokenSource();
}
private void OnDestroy()
{
cancellationTokenSource.Cancel();
}
private async void OnFingerDown(Finger obj)
{
IsTouching = true;
try
{
await Task.Delay(TimeSpan.FromSeconds(Time.deltaTime*2));
AllowTouch = !IsHoveringUI;
}
catch (OperationCanceledException)
{
}
}
private void OnFingerUp(Finger obj)
{
IsTouching = false;
}
public override void OnStart()
{
base.OnStart();
visualElement.RegisterCallback<PointerEnterEvent>(OnPointerEnter);
visualElement.RegisterCallback<PointerLeaveEvent>(OnPointerLevel);
}
private void OnPointerLevel(PointerLeaveEvent evt)
{
IsHoveringUI = true;
if (isMouseInput) AllowTouch = false;
}
private void OnPointerEnter(PointerEnterEvent evt)
{
IsHoveringUI = false;
if (isMouseInput) AllowTouch = true;
}
public bool OnCheck() => AllowTouch;
private bool isMouseInput => Mouse.current?.delta.ReadValue().sqrMagnitude > 0;
}
#if UNITY_EDITOR
[CustomEditor(typeof(UXAllowTouch))]
public class UXAllowTouchInspector:BITInspector<UXAllowTouch>
{
private Label allowTouchLabel;
private Label isHoveringUILabel;
private Label isTouching;
public override VisualElement CreateInspectorGUI()
{
FillDefaultInspector();
CreateSubTitle("Editor");
allowTouchLabel = root.Create<Label>();
isHoveringUILabel = root.Create<Label>();
isTouching = root.Create<Label>();
return root;
}
protected override void OnUpdate()
{
if (allowTouchLabel is null) return;
allowTouchLabel.text = agent.AllowTouch?"Allow Touch":"Block Touch";
isHoveringUILabel.text = agent.IsHoveringUI ? "Is Hovering UI" : "Not Hovering UI";
isTouching.text = agent.IsTouching ? "Is Touching" : "Not Touching";
allowTouchLabel.style.color = agent.AllowTouch?Color.green:Color.red;
isHoveringUILabel.style.color = agent.IsHoveringUI?Color.red:Color.green;
isTouching.style.color = agent.IsTouching?Color.green:Color.red;
}
}
#endif
}