/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (the "License");
* you may not use the Oculus SDK except in compliance with the License,
* which is provided at the time of installation or download, or which
* otherwise accompanies this software in either electronic or hard copy form.
*
* You may obtain a copy of the License at
*
* https://developer.oculus.com/licenses/oculussdk/
*
* Unless required by applicable law or agreed to in writing, the Oculus SDK
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace Oculus.Interaction
{
///
/// Exposes Unity pointer events that broadcast pointer events from an component (ex. a poke interactable on a button).
///
public class PointableUnityEventWrapper : MonoBehaviour
{
///
/// The Pointable component to wrap.
///
[Tooltip("The Pointable component to wrap.")]
[SerializeField, Interface(typeof(IPointable))]
private UnityEngine.Object _pointable;
private IPointable Pointable;
private HashSet _pointers;
///
/// Raised when the IPointable is released.
///
[Tooltip("Raised when the IPointable is released.")]
[SerializeField]
private UnityEvent _whenRelease;
///
/// Raised when the IPointable is hovered.
///
[Tooltip("Raised when the IPointable is hovered.")]
[SerializeField]
private UnityEvent _whenHover;
///
/// Raised when the IPointable is unhovered (it was hovered but now it isn't).
///
[Tooltip("Raised when the IPointable is unhovered (it was hovered but now it isn't).")]
[SerializeField]
private UnityEvent _whenUnhover;
///
/// Raised when the IPointable is selected.
///
[Tooltip("Raised when the IPointable is selected.")]
[SerializeField]
private UnityEvent _whenSelect;
///
/// Raised when the IPointable is unselected (it was selected but now it isn't).
///
[Tooltip("Raised when the IPointable is unselected (it was selected but now it isn't).")]
[SerializeField]
private UnityEvent _whenUnselect;
///
/// Raised when the IPointable moves.
///
[Tooltip("Raised when the IPointable moves.")]
[SerializeField]
private UnityEvent _whenMove;
///
/// Raised when the IPointable is canceled.
///
[Tooltip("Raised when the IPointable is canceled.")]
[SerializeField]
private UnityEvent _whenCancel;
///
/// Raised when the emits a
/// with the state.
///
public UnityEvent WhenRelease => _whenRelease;
///
/// Raised when the emits a
/// with the state.
///
public UnityEvent WhenHover => _whenHover;
///
/// Raised when the emits a
/// with the state.
///
public UnityEvent WhenUnhover => _whenUnhover;
///
/// Raised when the emits a
/// with the state.
///
public UnityEvent WhenSelect => _whenSelect;
///
/// Raised when the emits a
/// with the state.
///
public UnityEvent WhenUnselect => _whenUnselect;
///
/// Raised when the emits a
/// with the state.
///
public UnityEvent WhenMove => _whenMove;
///
/// Raised when the emits a
/// with the state.
///
public UnityEvent WhenCancel => _whenCancel;
protected bool _started = false;
protected virtual void Awake()
{
Pointable = _pointable as IPointable;
}
protected virtual void Start()
{
this.BeginStart(ref _started);
this.AssertField(Pointable, nameof(Pointable));
_pointers = new HashSet();
this.EndStart(ref _started);
}
protected virtual void OnEnable()
{
if (_started)
{
Pointable.WhenPointerEventRaised += HandlePointerEventRaised;
}
}
protected virtual void OnDisable()
{
if (_started)
{
Pointable.WhenPointerEventRaised -= HandlePointerEventRaised;
}
}
private void HandlePointerEventRaised(PointerEvent evt)
{
switch (evt.Type)
{
case PointerEventType.Hover:
_whenHover.Invoke(evt);
_pointers.Add(evt.Identifier);
break;
case PointerEventType.Unhover:
_whenUnhover.Invoke(evt);
_pointers.Remove(evt.Identifier);
break;
case PointerEventType.Select:
_whenSelect.Invoke(evt);
break;
case PointerEventType.Unselect:
if (_pointers.Contains(evt.Identifier))
{
_whenRelease.Invoke(evt);
}
_whenUnselect.Invoke(evt);
break;
case PointerEventType.Move:
_whenMove.Invoke(evt);
break;
case PointerEventType.Cancel:
_whenCancel.Invoke(evt);
_pointers.Remove(evt.Identifier);
break;
}
}
#region Inject
///
/// Injects all required dependencies for a dynamically instantiated
/// .
/// This method exists to support Interaction SDK's dependency injection pattern and is not
/// needed for typical Unity Editor-based usage.
///
public void InjectAllPointableUnityEventWrapper(IPointable pointable)
{
InjectPointable(pointable);
}
///
/// Sets the underlying for a dynamically instantiated
/// .
/// This method exists to support Interaction SDK's dependency injection pattern and is not
/// needed for typical Unity Editor-based usage.
///
public void InjectPointable(IPointable pointable)
{
_pointable = pointable as UnityEngine.Object;
Pointable = pointable;
}
#endregion
}
}