Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thestonefox/364f5217d5403df7d300d82bf0c2d4bc to your computer and use it in GitHub Desktop.
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
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;
}
}
@Maciej92Zareba
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment