/* * 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; using UnityEngine; namespace Oculus.Interaction { /// /// PointerInteractable provides a base template for any kind of interaction which can be characterized as, "pointing at something." /// Interactables of this kind, examples of which include and , /// receive s from interacting s and re-emit those events to describe /// their behavior during interaction, in addition to the signals and data provided by /// s. /// /// /// Like , this type has a /// [curiously recurring](https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern) generic argument /// , which should be the concrete interactable type which derives from this type and is /// uniquely associated with . /// public abstract class PointerInteractable : Interactable, IPointable where TInteractor : Interactor where TInteractable : PointerInteractable { [SerializeField, Interface(typeof(IPointableElement))] [Optional(OptionalAttribute.Flag.DontHide)] private UnityEngine.Object _pointableElement; /// /// The "think which can be pointed at" associated with this pointer interactable. This property is typically set through /// the Unity Editor and populated from there during MonoBehaviour start-up, but it can also be set programmatically using /// . This property is optional can can return null. /// /// /// For example, a might have a with which one can interact by /// pointing a 's ray at it, in which case the canvas would be the PointableElement. /// public IPointableElement PointableElement { get; protected set; } /// /// Implementation of ; for details, please refer to the related /// documentation provided for that interface. /// public event Action WhenPointerEventRaised = delegate { }; /// /// Internal API which publishes the provided , making sure that /// has the first opportunity to handle the event before it is emitted more broadly via . /// This method is automatically invoked by as part of the /// propagation process, and it should not be called directly from outside that process. /// /// public void PublishPointerEvent(PointerEvent evt) { if (PointableElement != null) { PointableElement.ProcessPointerEvent(evt); } WhenPointerEventRaised(evt); } protected override void Awake() { base.Awake(); PointableElement = _pointableElement as IPointableElement; } protected override void Start() { this.BeginStart(ref _started, () => base.Start()); if (_pointableElement != null) { this.AssertField(PointableElement, nameof(PointableElement)); } this.EndStart(ref _started); } #region Inject /// /// Sets the on a dynamically instantiated GameObject. This method exists to support /// Interaction SDK's dependency injection pattern and is not needed for typical Unity Editor-based usage. /// public void InjectOptionalPointableElement(IPointableElement pointableElement) { PointableElement = pointableElement; _pointableElement = pointableElement as UnityEngine.Object; } #endregion } }