Skip to content

Commit

Permalink
Merge pull request #1614 from thestonefox/feat/auto-secondary-grab
Browse files Browse the repository at this point in the history
feat(Interactions): option to automatically secondary grab object - fixes #1608
  • Loading branch information
thestonefox authored Nov 15, 2017
2 parents c7a696a + da9f5f8 commit f5d5a26
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 0 deletions.
14 changes: 14 additions & 0 deletions Assets/VRTK/Documentation/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -4102,8 +4102,11 @@ Attempt to automatically grab a specified Interactable Object.
* **Object Is Prefab:** If the `Object To Grab` is a prefab then this needs to be checked, if the `Object To Grab` already exists in the scene then this needs to be unchecked.
* **Clone Grabbed Object:** If this is checked then the `Object To Grab` will be cloned into a new Interactable Object and grabbed by the Interact Grab leaving the existing Interactable Object in the scene. This is required if the same Interactable Object is to be grabbed to multiple instances of Interact Grab. It is also required to clone a grabbed Interactable Object if it is a prefab as it needs to exist within the scene to be grabbed.
* **Always Clone On Enable:** If `Clone Grabbed Object` is checked and this is checked, then whenever this script is disabled and re-enabled, it will always create a new clone of the Interactable Object to grab. If this is unchecked then the original cloned Interactable Object will attempt to be grabbed again. If the original cloned object no longer exists then a new clone will be created.
* **Attempt Secondary Grab:** If this is checked then the `Object To Grab` will attempt to be secondary grabbed as well as primary grabbed.
* **Interact Touch:** The Interact Touch to listen for touches on. If the script is being applied onto a controller then this parameter can be left blank as it will be auto populated by the controller the script is on at runtime.
* **Interact Grab:** The Interact Grab to listen for grab actions on. If the script is being applied onto a controller then this parameter can be left blank as it will be auto populated by the controller the script is on at runtime.
* **Secondary Interact Touch:** The secondary controller Interact Touch to listen for touches on. If this field is left blank then it will be looked up on the opposite controller script alias at runtime.
* **Secondary Interact Grab:** The secondary controller Interact Grab to listen for grab actions on. If this field is left blank then it will be looked up on the opposite controller script alias at runtime.

### Class Events

Expand Down Expand Up @@ -8601,6 +8604,17 @@ The IsControllerLeftHand method is used to check if a given controller game obje

The IsControllerRightHand method is used to check if a given controller game object is the right handed controller.

#### GetOppositeHand/1

> `public static SDK_BaseController.ControllerHand GetOppositeHand(SDK_BaseController.ControllerHand currentHand)`

* Parameters
* `SDK_BaseController.ControllerHand currentHand` - The current hand.
* Returns
* `SDK_BaseController.ControllerHand` - The opposite hand.

The GetOppositeHand method returns the other hand type from the current hand given.

#### GetActualController/1

> `public static GameObject GetActualController(GameObject givenController)`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,19 @@ public class VRTK_ObjectAutoGrab : MonoBehaviour
public bool cloneGrabbedObject;
[Tooltip("If `Clone Grabbed Object` is checked and this is checked, then whenever this script is disabled and re-enabled, it will always create a new clone of the Interactable Object to grab. If this is unchecked then the original cloned Interactable Object will attempt to be grabbed again. If the original cloned object no longer exists then a new clone will be created.")]
public bool alwaysCloneOnEnable;
[Tooltip("If this is checked then the `Object To Grab` will attempt to be secondary grabbed as well as primary grabbed.")]
public bool attemptSecondaryGrab;

[Header("Custom Settings")]

[Tooltip("The Interact Touch to listen for touches on. If the script is being applied onto a controller then this parameter can be left blank as it will be auto populated by the controller the script is on at runtime.")]
public VRTK_InteractTouch interactTouch;
[Tooltip("The Interact Grab to listen for grab actions on. If the script is being applied onto a controller then this parameter can be left blank as it will be auto populated by the controller the script is on at runtime.")]
public VRTK_InteractGrab interactGrab;
[Tooltip("The secondary controller Interact Touch to listen for touches on. If this field is left blank then it will be looked up on the opposite controller script alias at runtime.")]
public VRTK_InteractTouch secondaryInteractTouch;
[Tooltip("The secondary controller Interact Grab to listen for grab actions on. If this field is left blank then it will be looked up on the opposite controller script alias at runtime.")]
public VRTK_InteractGrab secondaryInteractGrab;

/// <summary>
/// Emitted when the object auto grab has completed successfully.
Expand Down Expand Up @@ -152,11 +158,29 @@ protected virtual IEnumerator AutoGrab()
interactTouch.ForceStopTouching();
interactTouch.ForceTouch(grabbableObject.gameObject);
interactGrab.AttemptGrab();
AttemptSecondaryGrab(grabbableObject);
OnObjectAutoGrabCompleted();
}
}
objectToGrab.disableWhenIdle = grabbableObjectDisableState;
grabbableObject.disableWhenIdle = grabbableObjectDisableState;
}

protected virtual void AttemptSecondaryGrab(VRTK_InteractableObject grabbableObject)
{
if (attemptSecondaryGrab)
{
SDK_BaseController.ControllerHand currentHand = VRTK_DeviceFinder.GetControllerHand(interactTouch.gameObject);
VRTK_ControllerReference oppositeControllerReference = VRTK_ControllerReference.GetControllerReference(VRTK_DeviceFinder.GetOppositeHand(currentHand));
if (VRTK_ControllerReference.IsValid(oppositeControllerReference))
{
secondaryInteractTouch = (secondaryInteractTouch == null ? oppositeControllerReference.scriptAlias.GetComponentInChildren<VRTK_InteractTouch>() : secondaryInteractTouch);
secondaryInteractGrab = (secondaryInteractGrab == null ? oppositeControllerReference.scriptAlias.GetComponentInChildren<VRTK_InteractGrab>() : secondaryInteractGrab);
secondaryInteractTouch.ForceStopTouching();
secondaryInteractTouch.ForceTouch(grabbableObject.gameObject);
secondaryInteractGrab.AttemptGrab();
}
}
}
}
}
17 changes: 17 additions & 0 deletions Assets/VRTK/Source/Scripts/Utilities/VRTK_DeviceFinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,23 @@ public static bool IsControllerRightHand(GameObject checkController)
return VRTK_SDK_Bridge.IsControllerRightHand(checkController);
}

/// <summary>
/// The GetOppositeHand method returns the other hand type from the current hand given.
/// </summary>
/// <param name="currentHand">The current hand.</param>
/// <returns>The opposite hand.</returns>
public static SDK_BaseController.ControllerHand GetOppositeHand(SDK_BaseController.ControllerHand currentHand)
{
switch (currentHand)
{
case SDK_BaseController.ControllerHand.Left:
return SDK_BaseController.ControllerHand.Right;
case SDK_BaseController.ControllerHand.Right:
return SDK_BaseController.ControllerHand.Left;
}
return currentHand;
}

/// <summary>
/// The GetActualController method will attempt to get the actual SDK controller object.
/// </summary>
Expand Down

0 comments on commit f5d5a26

Please sign in to comment.