Skip to content

Commit

Permalink
fix(Interaction): ensure auto grab works correctly with prefabs
Browse files Browse the repository at this point in the history
If a Prefab was attempted to be auto grabbed that was also set to
have `Disable On Idle` as true, then the prefab would clone and be
disabled at the point of auto grabbing and therefore drop to the
ground.

This fix adds an additional option to specify the `Object To Grab`
is a prefab and if it is then to disable the `Disable On Idle` check
during the auto grab and to reset it when it has completed.

Another option has been added that determines whether to always clone
the object when the script is re-enabled or whether to just attempt
to grab the original clone.
  • Loading branch information
thestonefox committed Jan 21, 2017
1 parent 492d593 commit 40ec5d0
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
34 changes: 33 additions & 1 deletion Assets/VRTK/Scripts/Interactions/VRTK_ObjectAutoGrab.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,31 @@ public class VRTK_ObjectAutoGrab : MonoBehaviour
{
[Tooltip("A game object (either within the scene or a prefab) that will be grabbed by the controller on game start.")]
public VRTK_InteractableObject objectToGrab;
[Tooltip("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.")]
public bool objectIsPrefab;
[Tooltip("If this is checked then the Object To Grab will be cloned into a new object and attached to the controller leaving the existing object in the scene. This is required if the same object is to be grabbed to both controllers as a single object cannot be grabbed by different controllers at the same time. It is also required to clone a grabbed object if it is a prefab as it needs to exist within the scene to be grabbed.")]
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 object to grab. If this is false then the original cloned 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;

private VRTK_InteractableObject previousClonedObject = null;

/// <summary>
/// The ClearPreviousClone method resets the previous cloned object to null to ensure when the script is re-enabled that a new cloned object is created, rather than the original clone being grabbed again.
/// </summary>
public void ClearPreviousClone()
{
previousClonedObject = null;
}

private void OnEnable()
{
//Must always clone if the object is a prefab
if (objectIsPrefab)
{
cloneGrabbedObject = true;
}

StartCoroutine(AutoGrab());
}

Expand All @@ -41,8 +61,18 @@ private IEnumerator AutoGrab()
yield return true;
}

bool grabbableObjectDisableState = objectToGrab.disableWhenIdle;

if (objectIsPrefab)
{
objectToGrab.disableWhenIdle = false;
}

VRTK_InteractableObject grabbableObject = objectToGrab;
VRTK_InteractableObject previousClonedObject = null;
if (alwaysCloneOnEnable)
{
ClearPreviousClone();
}

if (!controllerGrab.GetGrabbedObject())
{
Expand Down Expand Up @@ -72,6 +102,8 @@ private IEnumerator AutoGrab()
controllerGrab.AttemptGrab();
}
}
objectToGrab.disableWhenIdle = grabbableObjectDisableState;
grabbableObject.disableWhenIdle = grabbableObjectDisableState;
}
}
}
15 changes: 15 additions & 0 deletions DOCUMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -2596,7 +2596,22 @@ It is possible to automatically grab an Interactable Object to a specific contro
### Inspector Parameters

* **Object To Grab:** A game object (either within the scene or a prefab) that will be grabbed by the controller on game start.
* **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 object and attached to the controller leaving the existing object in the scene. This is required if the same object is to be grabbed to both controllers as a single object cannot be grabbed by different controllers at the same time. It is also required to clone a grabbed 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 object to grab. If this is false then the original cloned object will attempt to be grabbed again. If the original cloned object no longer exists then a new clone will be created.

### Class Methods

#### ClearPreviousClone/0

> `public void ClearPreviousClone()`
* Parameters
* _none_
* Returns
* _none_

The ClearPreviousClone method resets the previous cloned object to null to ensure when the script is re-enabled that a new cloned object is created, rather than the original clone being grabbed again.

### Example

Expand Down

0 comments on commit 40ec5d0

Please sign in to comment.