mixedreality/com.microsoft.mixedreality..../SDK/Features/UX/Interactable/Scripts/Events/InteractableOnPressReceiver.cs

112 lines
3.5 KiB
C#

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using Microsoft.MixedReality.Toolkit.Utilities.Editor;
using UnityEngine.Events;
namespace Microsoft.MixedReality.Toolkit.UI
{
/// <summary>
/// Basic press event receiver
/// </summary>
public class InteractableOnPressReceiver : ReceiverBase
{
/// <summary>
/// Invoked on pointer release
/// </summary>
[InspectorField(Type = InspectorField.FieldTypes.Event, Label = "On Release", Tooltip = "The button is released")]
public UnityEvent OnRelease = new UnityEvent();
/// <summary>
/// Invoked on pointer press
/// </summary>
public UnityEvent OnPress => uEvent;
/// <summary>
/// Type of valid interaction distances to fire press events
/// </summary>
public enum InteractionType
{
/// <summary>
/// Support Near and Far press interactions
/// </summary>
NearAndFar = 0,
/// <summary>
/// Support Near press interactions only
/// </summary>
NearOnly = 1,
/// <summary>
/// Support Far press interactions only
/// </summary>
FarOnly = 2
}
/// <summary>
/// Specify whether press event is for near or far interaction
/// </summary>
[InspectorField(Label = "Interaction Filter",
Tooltip = "Specify whether press event is for near or far interaction",
Type = InspectorField.FieldTypes.DropdownInt, Options = new string[] { "Near and Far", "Near Only", "Far Only" })]
public int InteractionFilter = (int)InteractionType.NearAndFar;
private bool hasDown;
private bool isNear = false;
/// <summary>
/// Receiver that raises press and release unity events
/// </summary>
public InteractableOnPressReceiver(UnityEvent ev) : base(ev, "OnPress") { }
/// <summary>
/// Receiver that raises press and release unity events
/// </summary>
public InteractableOnPressReceiver() : this(new UnityEvent()) { }
/// <summary>
/// checks if the received interactable state matches the press filter
/// </summary>
/// <returns>true if interactable state matches filter</returns>
private bool IsFilterValid()
{
if (InteractionFilter == (int)InteractionType.FarOnly && isNear
|| InteractionFilter == (int)InteractionType.NearOnly && !isNear)
{
return false;
}
else
{
return true;
}
}
/// <inheritdoc />
public override void OnUpdate(InteractableStates state, Interactable source)
{
bool hadDown = hasDown;
hasDown = state.GetState(InteractableStates.InteractableStateEnum.Pressed).Value > 0;
if (hasDown != hadDown)
{
if (hasDown)
{
isNear = state.GetState(InteractableStates.InteractableStateEnum.PhysicalTouch).Value > 0;
if (IsFilterValid())
{
uEvent.Invoke();
}
}
else
{
if (IsFilterValid())
{
OnRelease.Invoke();
}
}
}
}
}
}