namespace VRTK.Prefabs.Interactions.Interactables
{
using UnityEngine;
using UnityEngine.Events;
using System;
using System.Collections.Generic;
using Malimbe.XmlDocumentationAttribute;
using Malimbe.PropertySerializationAttribute;
using Malimbe.MemberClearanceMethod;
using Malimbe.MemberChangeMethod;
using Zinnia.Rule;
using Zinnia.Extension;
using Zinnia.Data.Attribute;
using Zinnia.Data.Collection.List;
using Zinnia.Tracking.Collision;
using VRTK.Prefabs.Interactions.Interactors;
using VRTK.Prefabs.Interactions.Interactables.Touch;
using VRTK.Prefabs.Interactions.Interactables.Grab;
///
/// The public interface into the Interactable Prefab.
///
public class InteractableFacade : MonoBehaviour
{
///
/// Defines the event with the .
///
[Serializable]
public class UnityEvent : UnityEvent
{
}
#region Touch Events
///
/// Emitted when the Interactable is touched for the first time by an Interactor.
///
[Header("Touch Events"), DocumentedByXml]
public UnityEvent FirstTouched = new UnityEvent();
///
/// Emitted when an Interactor touches the Interactable.
///
[DocumentedByXml]
public UnityEvent Touched = new UnityEvent();
///
/// Emitted when an Interactor stops touching the Interactable.
///
[DocumentedByXml]
public UnityEvent Untouched = new UnityEvent();
///
/// Emitted when the Interactable is untouched for the last time by an Interactor.
///
[DocumentedByXml]
public UnityEvent LastUntouched = new UnityEvent();
#endregion
#region Grab Events
///
/// Emitted when the Interactable is grabbed for the first time by an Interactor.
///
[Header("Grab Events"), DocumentedByXml]
public UnityEvent FirstGrabbed = new UnityEvent();
///
/// Emitted when an Interactor grabs the Interactable.
///
[DocumentedByXml]
public UnityEvent Grabbed = new UnityEvent();
///
/// Emitted when an Interactor ungrabs the Interactable.
///
[DocumentedByXml]
public UnityEvent Ungrabbed = new UnityEvent();
///
/// Emitted when the Interactable is ungrabbed for the last time by an Interactor.
///
[DocumentedByXml]
public UnityEvent LastUngrabbed = new UnityEvent();
#endregion
#region Restriction Settings
///
/// The rule to determine what is not allowed to touch this interactable.
///
[Serialized, Cleared]
[field: Header("Restriction Settings"), DocumentedByXml]
public RuleContainer DisallowedTouchInteractors { get; set; }
///
/// The rule to determine what is not allowed to grab this interactable.
///
[Serialized, Cleared]
[field: DocumentedByXml]
public RuleContainer DisallowedGrabInteractors { get; set; }
#endregion
#region Container Settings
///
/// The overall container for the interactable consumers.
///
[Serialized, Cleared]
[field: Header("Container Settings"), DocumentedByXml]
public GameObject ConsumerContainer { get; set; }
[Serialized, Cleared]
[field: DocumentedByXml]
///
/// The for the overall collisions.
///
public Rigidbody ConsumerRigidbody { get; set; }
#endregion
#region Reference Settings
///
/// The linked .
///
[Serialized]
[field: Header("Reference Settings"), DocumentedByXml, Restricted]
public CollisionNotifier CollisionNotifier { get; protected set; }
///
/// The linked .
///
[Serialized]
[field: DocumentedByXml, Restricted]
public GameObjectObservableList ActiveCollisions { get; protected set; }
///
/// The linked Touch Internal Setup.
///
[Serialized]
[field: DocumentedByXml, Restricted]
public TouchInteractableConfigurator TouchConfiguration { get; protected set; }
///
/// The linked Grab Internal Setup.
///
[Serialized]
[field: DocumentedByXml, Restricted]
public GrabInteractableConfigurator GrabConfiguration { get; protected set; }
#endregion
///
/// A collection of Interactors that are currently touching the Interactable.
///
public IReadOnlyList TouchingInteractors => TouchConfiguration.TouchingInteractors;
///
/// A collection of Interactors that are currently grabbing the Interactable.
///
public IReadOnlyList GrabbingInteractors => GrabConfiguration.GrabbingInteractors;
///
/// Determines if the grab type is set to toggle.
///
public bool IsGrabTypeToggle => GrabConfiguration.IsGrabTypeToggle;
///
/// Whether the Interactable is currently being touched by any valid Interactor.
///
public bool IsTouched => TouchingInteractors.Count > 0;
///
/// Whether the Interactable is currently being grabbed by any valid Interactor.
///
public bool IsGrabbed => GrabbingInteractors.Count > 0;
///
/// Attempt to grab the Interactable to the given that contains an Interactor.
///
/// The GameObject that the Interactor is on.
public virtual void Grab(GameObject interactor)
{
Grab(interactor.TryGetComponent(true, true));
}
///
/// Attempt to grab the Interactable to the given Interactor.
///
/// The Interactor to attach the Interactable to.
public virtual void Grab(InteractorFacade interactor)
{
GrabConfiguration.Grab(interactor);
}
///
/// Attempt to ungrab the Interactable to the given that contains an Interactor.
///
/// The GameObject that the Interactor is on.
public virtual void Ungrab(GameObject interactor)
{
Ungrab(interactor.TryGetComponent(true, true));
}
///
/// Attempt to ungrab the Interactable.
///
/// The Interactor to ungrab from.
public virtual void Ungrab(InteractorFacade interactor)
{
GrabConfiguration.Ungrab(interactor);
}
///
/// Attempt to ungrab the Interactable at a specific grabbing index.
///
/// The Interactor sequence index to ungrab from.
public virtual void Ungrab(int sequenceIndex = 0)
{
GrabConfiguration.Ungrab(sequenceIndex);
}
///
/// Configures any container data to the sub setup components.
///
protected virtual void ConfigureContainer()
{
TouchConfiguration.ConfigureContainer();
GrabConfiguration.ConfigureContainer();
}
///
/// Called after has been changed.
///
[CalledAfterChangeOf(nameof(DisallowedTouchInteractors))]
protected virtual void OnAfterDisallowedTouchInteractorsChange()
{
TouchConfiguration.TouchValidity.ReceiveValidity = DisallowedTouchInteractors;
}
///
/// Called after has been changed.
///
[CalledAfterChangeOf(nameof(DisallowedGrabInteractors))]
protected virtual void OnAfterDisallowedGrabInteractorsChange()
{
GrabConfiguration.GrabReceiver.GrabValidity.ReceiveValidity = DisallowedGrabInteractors;
}
///
/// Called after has been changed.
///
[CalledAfterChangeOf(nameof(ConsumerContainer))]
protected virtual void OnAfterConsumerContainerChange()
{
ConfigureContainer();
}
///
/// Called after has been changed.
///
[CalledAfterChangeOf(nameof(ConsumerRigidbody))]
protected virtual void OnAfterConsumerRigidbodyChange()
{
ConfigureContainer();
}
}
}