Created
May 24, 2022 19:01
-
-
Save thestonefox/364f5217d5403df7d300d82bf0c2d4bc to your computer and use it in GitHub Desktop.
Tilia Interactables Example of how to get two handed grabbing to work with an orientation grabbed object so either hand can be holding it
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using Tilia.Interactions.Interactables.Interactables; | |
using Tilia.Interactions.Interactables.Interactables.Grab.Action; | |
using Tilia.Interactions.Interactables.Interactables.Grab.Provider; | |
using Tilia.Interactions.Interactables.Interactors; | |
using UnityEngine; | |
using Zinnia.Data.Collection.Stack; | |
public class OrientationFollowPrimarySecondarySwapper : MonoBehaviour | |
{ | |
[SerializeField] | |
private InteractableFacade interactable; | |
public InteractableFacade Interactable | |
{ | |
get { return interactable; } | |
set | |
{ | |
RegisterForcePoppedListener(interactable); | |
interactable = value; | |
UnregisterForcePoppedListener(interactable); | |
} | |
} | |
[SerializeField] | |
private int stackIndex; | |
public int StackIndex | |
{ | |
get { return stackIndex; } | |
set { stackIndex = value; } | |
} | |
protected Coroutine swapToPrecisionRoutine; | |
protected Coroutine revertToOrientationRoutine; | |
protected virtual void OnEnable() | |
{ | |
RegisterForcePoppedListener(Interactable); | |
} | |
protected virtual void OnDisable() | |
{ | |
StopRoutine(ref swapToPrecisionRoutine); | |
StopRoutine(ref revertToOrientationRoutine); | |
UnregisterForcePoppedListener(Interactable); | |
Interactable.Grabbed.RemoveListener(SecondHandGrab); | |
Interactable.LastUngrabbed.RemoveListener(SwapBackToOrientation); | |
} | |
protected virtual void RegisterForcePoppedListener(InteractableFacade data) | |
{ | |
GameObjectObservableStack stack = GetStack(data); | |
if (stack == null) | |
{ | |
return; | |
} | |
stack.ElementEvents[1].ForcePopped.AddListener(SwapToPrecision); | |
} | |
protected virtual void UnregisterForcePoppedListener(InteractableFacade data) | |
{ | |
GameObjectObservableStack stack = GetStack(data); | |
if (stack == null) | |
{ | |
return; | |
} | |
stack.ElementEvents[1].ForcePopped.RemoveListener(SwapToPrecision); | |
} | |
protected virtual GameObjectObservableStack GetStack(InteractableFacade input) | |
{ | |
if (input == null) | |
{ | |
return null; | |
} | |
GrabInteractableStackInteractorProvider provider = (GrabInteractableStackInteractorProvider)input.Configuration.GrabConfiguration.GrabProviderOptions[StackIndex]; | |
return provider != null && provider.EventStack.ElementEvents.Count > 1 ? provider.EventStack : null; | |
} | |
protected virtual bool SetGrabOffset(GrabInteractableFollowAction.OffsetType offsetType) | |
{ | |
GrabInteractableFollowAction followAction = (GrabInteractableFollowAction)Interactable.Configuration.GrabConfiguration.PrimaryAction; | |
if (followAction == null) | |
{ | |
return false; | |
} | |
followAction.GrabOffset = offsetType; | |
return true; | |
} | |
protected virtual void StopRoutine(ref Coroutine routine) | |
{ | |
if (routine != null) | |
{ | |
StopCoroutine(routine); | |
routine = null; | |
} | |
} | |
protected virtual void SwapToPrecision(GameObject interactor) | |
{ | |
if (!SetGrabOffset(GrabInteractableFollowAction.OffsetType.PrecisionPoint)) | |
{ | |
return; | |
} | |
StopRoutine(ref swapToPrecisionRoutine); | |
swapToPrecisionRoutine = StartCoroutine(SwapToPrecisionAtEndOfFrame(interactor)); | |
} | |
protected GameObject primaryController; | |
protected GameObject secondaryController; | |
protected WaitForEndOfFrame endOfFrameInstruction = new WaitForEndOfFrame(); | |
protected virtual IEnumerator SwapToPrecisionAtEndOfFrame(GameObject interactor) | |
{ | |
yield return endOfFrameInstruction; | |
secondaryController = interactor; | |
Interactable.Grab(interactor); | |
Interactable.Grabbed.AddListener(SecondHandGrab); | |
swapToPrecisionRoutine = null; | |
} | |
protected virtual void SecondHandGrab(InteractorFacade interactor) | |
{ | |
primaryController = interactor.gameObject; | |
Interactable.LastUngrabbed.AddListener(SwapBackToOrientation); | |
UnregisterForcePoppedListener(Interactable); | |
Interactable.UngrabAll(); | |
} | |
protected virtual void SwapBackToOrientation(InteractorFacade interactor) | |
{ | |
if (!SetGrabOffset(GrabInteractableFollowAction.OffsetType.OrientationHandle)) | |
{ | |
return; | |
} | |
Interactable.Grabbed.RemoveListener(SecondHandGrab); | |
Interactable.LastUngrabbed.RemoveListener(SwapBackToOrientation); | |
StopRoutine(ref revertToOrientationRoutine); | |
revertToOrientationRoutine = StartCoroutine(RevertBackToOrientationAtEndOfFrame()); | |
} | |
protected virtual IEnumerator RevertBackToOrientationAtEndOfFrame() | |
{ | |
yield return endOfFrameInstruction; | |
Interactable.Grab(primaryController); | |
Interactable.Grab(secondaryController); | |
RegisterForcePoppedListener(Interactable); | |
revertToOrientationRoutine = null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Posted bug report here: ExtendRealityLtd/Tilia.Interactions.Interactables.Unity#135