Forum Discussion
DeakinCUBE
6 years agoExplorer
How can I toggle (enable / disable) OVRGrabbable on a Unity game object in script?
I would like to toggle OVRGrabbale on a game object, subject to a boolean condition.
As an example, a virtual "screw":
- when it is screwed into a hole (engaged), it SHOULD NOT be grabbable by the player
- when it is unscrewed (dis-engaged), it SHOULD be grabbable by the player
My understanding is the boolean attribute "allowOffhandGrab" can / should be used for this, however this attribute is only read-only in OVRGrabbable.cs.
Adding a setter in OVRGrabbable.cs has not had any effect on disabling OVRGrabbable during runtime.
As a partial workaround solution, I've also tried enabling / disabling the game object's collider and rigidbody.detection components. Both of these work by allowing me to toggle the object's "grabbability" however creates interactivity issues with other game objects, so is not a feasible solution.
Can someone please help?
Thank you.
As an example, a virtual "screw":
- when it is screwed into a hole (engaged), it SHOULD NOT be grabbable by the player
- when it is unscrewed (dis-engaged), it SHOULD be grabbable by the player
My understanding is the boolean attribute "allowOffhandGrab" can / should be used for this, however this attribute is only read-only in OVRGrabbable.cs.
Adding a setter in OVRGrabbable.cs has not had any effect on disabling OVRGrabbable during runtime.
/// <summary>
/// If true, the object can currently be grabbed.
/// </summary>
public bool allowOffhandGrab
{
get { return m_allowOffhandGrab; }
set { m_allowOffhandGrab = value; } // Added to test grabbablity switching (ie. on / off) but does not seem to work
}
As a partial workaround solution, I've also tried enabling / disabling the game object's collider and rigidbody.detection components. Both of these work by allowing me to toggle the object's "grabbability" however creates interactivity issues with other game objects, so is not a feasible solution.
Can someone please help?
Thank you.
- I've managed to solve it...turns out it was very easy but requires changes to OVRGrabbable.cs and OVRGrabber.cs
For anyone else who comes across this problem:
Step 1)
In OVRGrabbable.cs
public bool allowOffhandGrab{get { return m_allowOffhandGrab; }set { m_allowOffhandGrab = value; } // Add this line to allow write-access to attribute}
Step 2)
In OVRGrabber.cs:protected virtual void GrabBegin(){float closestMagSq = float.MaxValue;OVRGrabbable closestGrabbable = null;Collider closestGrabbableCollider = null;// Iterate grab candidates and find the closest grabbable candidateforeach (OVRGrabbable grabbable in m_grabCandidates.Keys){//bool canGrab = !(grabbable.isGrabbed && !grabbable.allowOffhandGrab); // was thisbool canGrab = !grabbable.isGrabbed && grabbable.allowOffhandGrab; // change to thisif (!canGrab){continue;}
Step 3)
Now you can toggle OVRGrabbable on/off in script by referencing the OVRGrabbable script and then setting "allowOffHandGrab" to true (can grab) or false (cannot grab)
Eg:public class Screw : MonoBehaviour{private OVRGrabbable _OVRGrabbable;private void Awake(){_OVRGrabbable = GetComponent<OVRGrabbable>();}
public void ToggleGrab(bool value)
{
_OVRGrabbable.allowOffhandGrab = value; // True = can grab; False = cannot grab
}
}
Hope this helps anyone else who encounters this problem.
:-)
8 Replies
- DeakinCUBEExplorerI've managed to solve it...turns out it was very easy but requires changes to OVRGrabbable.cs and OVRGrabber.cs
For anyone else who comes across this problem:
Step 1)
In OVRGrabbable.cs
public bool allowOffhandGrab{get { return m_allowOffhandGrab; }set { m_allowOffhandGrab = value; } // Add this line to allow write-access to attribute}
Step 2)
In OVRGrabber.cs:protected virtual void GrabBegin(){float closestMagSq = float.MaxValue;OVRGrabbable closestGrabbable = null;Collider closestGrabbableCollider = null;// Iterate grab candidates and find the closest grabbable candidateforeach (OVRGrabbable grabbable in m_grabCandidates.Keys){//bool canGrab = !(grabbable.isGrabbed && !grabbable.allowOffhandGrab); // was thisbool canGrab = !grabbable.isGrabbed && grabbable.allowOffhandGrab; // change to thisif (!canGrab){continue;}
Step 3)
Now you can toggle OVRGrabbable on/off in script by referencing the OVRGrabbable script and then setting "allowOffHandGrab" to true (can grab) or false (cannot grab)
Eg:public class Screw : MonoBehaviour{private OVRGrabbable _OVRGrabbable;private void Awake(){_OVRGrabbable = GetComponent<OVRGrabbable>();}
public void ToggleGrab(bool value)
{
_OVRGrabbable.allowOffhandGrab = value; // True = can grab; False = cannot grab
}
}
Hope this helps anyone else who encounters this problem.
:-) - juruhnExplorerHave the same issue and tried your solution but it does not seem to matter if the allowOffhandGrab is true or false (either from inspector nor script). It is always grabable.
Although documentation states that it should disable the grabbing.
Strange.
Unity v2019.3.0f3, Oculus Utilities v1.44.0, OVRPlugin v1.44.0, SDK v1.44.0. - nZer0_Honored Guest
In my case, with DistanceGrabber, I added Step 4 and it solved.
Step 4)
In DistanceGrabber.csprotected bool FindTarget(out DistanceGrabbable dgOut, out Collider collOut){dgOut = null;collOut = null;float closestMagSq = float.MaxValue;// First test for objects within the grab volume, if we're using those.// (Some usage of DistanceGrabber will not use grab volumes, and will only// use spherecasts, and that's supported.)foreach (OVRGrabbable cg in m_grabCandidates.Keys){DistanceGrabbable grabbable = cg as DistanceGrabbable;//bool canGrab = grabbable != null && grabbable.InRange && !(grabbable.isGrabbed && !grabbable.allowOffhandGrab); // was this
bool canGrab = grabbable != null && grabbable.InRange && (!grabbable.isGrabbed && grabbable.allowOffhandGrab);if (canGrab && m_grabObjectsInLayer >= 0) canGrab = grabbable.gameObject.layer == m_grabObjectsInLayer;if (!canGrab){continue;} - DeakinCUBEExplorerHi juruhn
Sorry I just saw your reply. Did you manage to solve your issue? - juruhnExplorerHi DeakinCUBE,
Due to time pressure, I made a workaround.
As I exactly know when they need to be grabable and not, I just add and remove the OVRGrabbable script to the object.
There were a few updates by now, so maybe the issue is fixed. Haven't tested it yet.
Happy to hear others experiences with the OVRGrabbable. - DeakinCUBEExplorerHi Juruhn,
Glad to hear you got it working. For something as fundamental as being able to restrict / allow vr grabbing of certain objects as circumstances require (in real time), it seems odd to me that Oculus have not incorporated this into their scripts - we're talking a couple of lines of code. - juruhnExplorerTotally agree, that's why I was really surprised and thought I was missing something.
For now it works with current solution, but I will look into it later, there must be a 'ready to go' solution provided that actually works out of the box. (although its new technology) - JeceyHonored Guest
Writing this in case people still encounter this issue. Personally I found it more effective to make a subclass of OVRGrabbable by inheriting it instead of inheriting Monobehaviour. This allows you to make edits to some of the member variables without needing to change the library code while also allowing you to override from GrabBegin and GrabEnd for more flexibility.
Quick Links
- Horizon Developer Support
- Quest User Forums
- Troubleshooting Forum for problems with a game or app
- Quest Support for problems with your device
Other Meta Support
Related Content
- 10 months ago
- 3 months ago
- 9 months ago