112 lines
3.5 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|