Forum Discussion
jaumet2000
4 years agoHonored Guest
Check if an object is grabbed
Hello guys. I can't find a way to check if an object is grabbed or not, a boolean that is true if it is grabbed and false if it is not. The attached image is the components that the object that I want that variable to have.
I'm using Oculus sdk Integration in Unity 2020.3.10.
Any help is appreciated. Thank you
There might be an easier solution but when I did this, I also wanted a few other features so I created my own ITransformer and put it in the Grabbable Script. Once you do this, you can just copy-paste the code in the default ITransformer you want. In an ITransformer, there is a method called BeginTransform() that is called when an object is first grabbed and EndTransform() when it is unselected. I'd recommend saving a bool somewhere else that is changed by these methods.
EDIT: If you want to get the gameobject inside the iTransformer script use this (assuming the script is on the gameobject):
_grabbable.Transform.gameObject
16 Replies
Replies have been turned off for this discussion
- ExiusHonored Guest
Hey, did you find a solution? I'm trying to understand the same thing..
- WolffRuoffExplorer
There might be an easier solution but when I did this, I also wanted a few other features so I created my own ITransformer and put it in the Grabbable Script. Once you do this, you can just copy-paste the code in the default ITransformer you want. In an ITransformer, there is a method called BeginTransform() that is called when an object is first grabbed and EndTransform() when it is unselected. I'd recommend saving a bool somewhere else that is changed by these methods.
EDIT: If you want to get the gameobject inside the iTransformer script use this (assuming the script is on the gameobject):
_grabbable.Transform.gameObject- Shashwatmehrotra007Honored Guest
Hey, Can you share your iTransformer script or explain how it was functioning so that I can understand your answer a little better ? I am trying to get a boolean for grabbing interaction and need help.
Thank you.- FahruzExpert Protege
If you're using simple grabbing, you can just extend the OneGrabFreeTransformer class (and also implement the interface so that you can override the methods) and assign it to the "One Grab Transformer" property in the Grabbable.
My script, which uses events looks like this:
using UnityEngine; using Oculus.Interaction; public class ObjectGrabbedEventSender : OneGrabFreeTransformer, ITransformer { public delegate void ObjectGrabbed(GameObject source); public event ObjectGrabbed onObjectGrabbed; public delegate void ObjectMoved(GameObject source); public event ObjectMoved onObjectMoved; public delegate void ObjectReleased(GameObject source); public event ObjectReleased onObjectReleased; public new void Initialize(IGrabbable grabbable) { base.Initialize(grabbable); } public new void BeginTransform() { base.BeginTransform(); onObjectGrabbed?.Invoke(gameObject); } public new void UpdateTransform() { base.UpdateTransform(); onObjectMoved?.Invoke(gameObject); } public new void EndTransform() { //Parent class does nothing with that method so no need to call it onObjectReleased?.Invoke(gameObject); } }
- 0ctipusPrimeExplorer
For those who struggled to follow the solution like me:
1. Pick one of the prepared ITransformers that is closest to your vision (eg. OneGrabFreeTransformer, TwoGrabPlaneTransformer). They can be found in the Grabbable folder of the package Meta XR Interaction SDK, but you can just search for them in your project tab in Unity.
2. Create a copy of it into your assets (because you can't modify them in the package)
3. Modify functionality however you see fit.
For example add `GameManager.ObjectSelected(_grabbable.Transform.gameObject);` like me to track which object has been selected. The `_grabbable.Transform.gameObject` is the reference to the object that is grabbed. To make my example with you need to implement event triggering ObjectSelected method in the GameManager. BeginTransform might look like this:
public void BeginTransform()
{
Pose grabPoint = _grabbable.GrabPoints[0];
var targetTransform = _grabbable.Transform;
_grabDeltaInLocalSpace = new Pose(targetTransform.InverseTransformVector(grabPoint.position - targetTransform.position),
Quaternion.Inverse(grabPoint.rotation) * targetTransform.rotation);
GameManager.ObjectSelected(_grabbable.Transform.gameObject);
}4. Add this new ITransform script to the grabbable object
5. Find Grabbable in the inspector of the GameObject, expand the Optionals and drag the component (that is attached to the same game object from step 4) into the field One (or Two) Grab Transformer.
6. Test whether your changes in the script had an effect.
This is how the object you want to grab might look like.
- hannhuddHonored Guest
This was so helpful-- thank you!
- hasenavExplorer
Hi! Yo can check the state in HandGrabInteractor:
private HandGrabInteractor handGrab;
....
if (InteractorState.Select == handGrab.State) -- then a object is grabbed- Vr-Number1-BachelorHonored Guest
Hey, I would love to know where you found those states. I am in desperate need for Documentation, but have found that Meta fails to provide any, at least any that are easily accessible or findable.
- FahruzExpert Protege
As you say, there doesn't seem to be any doc about those states so you have to look in the source code of InteractorState to find out all the states of that enum, which are:
Normal,
Hover,
Select,
Disabled
- JVibes55Member
I solved this in a different way. I needed to know which hand was grabbing the object, not just if it was grabbed. There is a property on the HandGrabInteractable called Interactors that populates with which interactors are grabbing it. So, I added tags to the left and right HandGrabInteractors in my OVRCameraRig and then added this code in a script on the same GameObject as the HandGrabInteractable. If you just need to know if it is grabbed, you probably just to need to know if this is null or not.
public class SomeClass : MonoBehavior { private HandGrabInteractable _interactable; void Start() { _interactable = gameObject.GetComponent<HandGrabInteractable>(); } void Update(){ var hand = _interactable.Interactors.FirstOrDefault<HandGrabInteractor>(); if (hand != null) { Debug.Log("Connected to hand " + hand.gameObject.tag); // ... do something interesting with this knowledge } } }- gb1982gbExplorer
This was eassy!
- Dev-FirebirdVRHonored Guest
The solution I used to check if a particular object is grabbed.
Is to use SelectingPointsCount in the Grabbable script, that is attached to the target object.
It goes:public Grabbable _grabbable;private void Update(){if (_grabbable.SelectingPointsCount > 0) // is grabbing{ //Your code }} - sirtario9Honored Guest
Hey!
I had a similar problem, I just want to share my solution.This was made with Meta SDK v65 and Unity 2022.3.12f1
How it works:
Oculus Interactions works with 4 states that both the interactors and interactables have. https://developer.oculus.com/documentation/unity/unity-isdk-interactor-interactable-lifecycle/
If you have an Object you want to grab, you can add the Grab Interaction via the new Quick-Actions feature. This will add a Child GameObject that holds all the Grab scripts Oculus needs and set up a rigid body if not already present. You can then simply get the current state of an Interactor or Interactable via the e.g.:
GrabInteractable.StateUsing this
I then wrote a script that one can attach to the GameObject.The script itself is used to snap two GameObjects together. for this to happen I needed to detect if a GameObject was let go. it holds the last state and gets the current state to detect the state change. The script assumes that the GrabInteractable is attached to the Generated Child GameObject.
//get States for detecting if Brick has been let go LastState = CurrentState; CurrentState = GetComponentInChildren<Oculus.Interaction.GrabInteractable>().State; //detect if grabbed brick is let go // Select => currently grabbed // Normal/Hover => not grabbed if (LastState == Oculus.Interaction.InteractableState.Select && (CurrentState == Oculus.Interaction.InteractableState.Normal || CurrentState == Oculus.Interaction.InteractableState.Hover)) { DetermineSnapKind(); }Scene Graph for good measure.
- volo.voloHonored Guest
Hello,
I have tried your solution and written a following script:using System.Collections; using System.Collections.Generic; using UnityEngine; using Oculus.Interaction; public class GrabDetection : MonoBehaviour { private GrabInteractable _grabInteractable; // Start is called before the first frame update void Start() { _grabInteractable = GetComponentInChildren<GrabInteractable>(); if (_grabInteractable == null) { Debug.LogError("GrabInteractable component not found in children."); return; } } // Update is called once per frame void Update() { if (_grabInteractable == null) { return; } var currentState = _grabInteractable.State; Debug.Log("Current state: " + currentState); if (currentState == InteractableState.Normal) { Debug.Log("Current state: OBJECT NOT GRABBED"); } if (currentState == InteractableState.Select) { Debug.Log("Current state: OBJECT GRABBED"); } } }
I am grabbing an object but select does not get there. Console just keeps printing "Current state: normal". Do you have an idea what could I check?
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
- 2 years ago
- 8 years agoAnonymous