Search Unity

Grabbed objects going through walls, other objects

Discussion in 'AR/VR (XR) Discussion' started by bugzilla, Aug 12, 2017.

  1. bugzilla

    bugzilla

    Joined:
    Dec 9, 2008
    Posts:
    196
    I am using the Oculus to develop. It comes with a Prefab that lets you pick up and manipulate objects, which works perfectly except once an object is picked up it no longer responds to physics like normal. While you are holding it the object can go through walls and other objects even if they have Rigidbodies and colliders attached. I have tried changing the Collision Detection from Discreet to Continuous but no luck.

    Has anyone solved this issue? i would think it would be a common behavior the Unity community would benefit from knowing how to solve.
     
  2. greggtwep16

    greggtwep16

    Joined:
    Aug 17, 2012
    Posts:
    1,546
    I've been trying to solve this for a update of a product in my signature.

    The fundamental problem is what you want to happen when you hit a collider that isn't supposed to move. Obviously there is no feedback on your hand where in real life if you touch the wall you cannot break through but in VR this isn't possible so there are a couple of options.

    1. Break the grab when you hit the static collider.
    2. Ignore the collider and allow push through
    3. Save the position of the initial collision and "stick" the object there until you move back to the other side of wall.

    The Oculus sdk only does number 2. I've currently done 1 and 2. Option 3 doesn't feel right in my attempts at least so far. I was hoping it would work like games like Zelda but the main difference seems to be the control scheme. In non VR games controlled by a joystick not pushing through a wall is fairly easy because you actively have to push towards the wall and can detect the collision and push it back frame by frame. However, in VR since the controller has a distinct position once the controller pushes all the way through the collider you have nothing to go on. Also if you release while inside the collider it will throw the object the opposite direction. So far it seems like 1 and 2 are the only real options.
     
    systemicgames likes this.
  3. bugzilla

    bugzilla

    Joined:
    Dec 9, 2008
    Posts:
    196
    Thanks. Do you have some samples of the methods you have already tried?
     
  4. greggtwep16

    greggtwep16

    Joined:
    Aug 17, 2012
    Posts:
    1,546
    My product uses it's own API, so unfortunately the scripts won't compile without it, but you should be able to draw from the concepts. It's also not currently on the store version as it's going through beta testing currently for those that have elected to do so. But the concepts are as follows.

    Grabbing from laser pointer:
    Code (CSharp):
    1.         public override void Hover(Vector3 hitPosition, Transform pointerTransform)
    2.         {
    3.             hovering = true;
    4.             if (clicking)
    5.             {
    6.                 grabMode = true;
    7.                 laserTransform = pointerTransform;
    8.                 if (!previousClicking)
    9.                 {
    10.                     //first frame of grab get the distance
    11.                     currentDistance = (laserTransform.position - hitPosition).magnitude;
    12.                 }
    13.             }
    14.         }
    So basically it calculates the distance the object is from the controller when first grabbed

    Moving while grabbing:

    Code (CSharp):
    1. this.transform.position = laserTransform.position + laserTransform.forward * currentDistance;
    I have a lot of other stuff in my current beta for things like twisting for rotation and moving the object closer/farther based on pad clicks, but the main portion is just the above line. It's in FixedUpdate and moves the objects position based on the position of the pointer, it's forward direction and the current distance. If using just these 2 it's mostly analogous to the push through effect.

    Breaking collision when hitting a collider:
    Code (CSharp):
    1.         void OnCollisionEnter(Collision collision)
    2.         {
    3.             if (collisionsBreakGrab)
    4.             {
    5.                 grabMode = false;
    6.                 if (myRigidbody != null)
    7.                 {
    8.                     myRigidbody.velocity = Vector3.zero;
    9.                     myRigidbody.angularVelocity = Vector3.zero;
    10.                 }
    11.             }
    12.         }
    Hope those concepts help. I'm certainly open to other ideas but I'm not sure there is an ideal version like there is with a joystick.
     
  5. bugzilla

    bugzilla

    Joined:
    Dec 9, 2008
    Posts:
    196
    Awesome. You rock!
     
    greggtwep16 likes this.
  6. ricogs400

    ricogs400

    Joined:
    Aug 4, 2017
    Posts:
    13
    Have you tried VRTK for their Interactable Grab scripts. There is a Grab Attach youtube tutorial video by VRTK and sample scene within VRTK showing the different grab options.
     
    KDevS likes this.
  7. Christian_Perri

    Christian_Perri

    Joined:
    Aug 7, 2022
    Posts:
    31
    io was thinking to create a trigger and when the object in your hand collide with that trigger you can reset the position where you want
     
  8. robijust

    robijust

    Joined:
    May 18, 2022
    Posts:
    1
    Is there a way to get it to just drop out of the hand on a collision
     
  9. arkantose

    arkantose

    Joined:
    Dec 22, 2021
    Posts:
    8
    Ya you can and there are several ways to do it.
    The laziest way I can think of is have an on trigger enter event.
    If a certain item hits, lets say a wall; that has a box collider on it that juts out off of it a little. Grab the object that hit the wall and turn its Grab layer to nothing. This will make the item drop from the users hand. You could also make a Invoke or coroutine that turns the layer on that item back to normal after so many seconds.

    Just make sure some time is passed to make the item not be within the hands grab collider. If you turn it back to a grab able layer the hand will just grab it back instantly unless the player let go of the button.