1
\$\begingroup\$

I need a way to carry objects on top of other objects in VR without jitterness causing the objects to fall through a tray for example.

I've tested with rigidbodies having very high friction, this does help with the unrealistic slipping off but both the jitterness of virtual reality and also the ability to teleport creates the need for a better solution.

A tray with two mugs

I'm thinking of some kind of magnet-like system where if you drop an item onto the tray, it becomes stuck until you manually take it off. This would be simple by just checking collisions, parenting the object and making it Kinematic, the issue is it still needs to follow physics where if you tip the tray the object should still be able to fall off.

Has anyone implemented anything like this before or have any ideas on the best way to solve this situation?

\$\endgroup\$
1
  • \$\begingroup\$ Is there something you find unsatisfactory about the solution you've described in your question? What should answers seek to improve over what you've already proposed? \$\endgroup\$
    – DMGregory
    Nov 28, 2023 at 14:07

2 Answers 2

2
\$\begingroup\$

It sounds like you've already figured out the solution:

I'm thinking of some kind of magnet-like system where if you drop an item onto the tray, it becomes stuck until you manually take it off.

From reading your post, it sounds like exactly what you need. When an object is placed on the tray, make it a child of the tray, and make it kinematic, so that it still interacts with other objects, but it isn't affected by gravity.

When a user attempts to grab one of those objects on the tray, detach it and disable kinematics, so that it is a physics object again.

It should also solve your teleportation feature, as objects should remain attached on the tray.

This of course is heavily dependent on what kind of game you are going for, but from what you've described so far, this technique should work well.

\$\endgroup\$
3
  • \$\begingroup\$ It's more a question of realism. If I were to simply do a "on contact, set kinematic" then the mug would just stick, even if dropped on it's edge. This also wouldn't take into account the tipping of the tray. So my question is more if there is a better way of doing this, for example calculating when the mug's rigidbody has come to a rest then attach it, but then that wouldn't work as you need to take into account if you're already holding the tray and it jittering slightly. \$\endgroup\$ Nov 28, 2023 at 15:37
  • \$\begingroup\$ For example only making the mug a child of the tray when it hit's, but becomes slow, almost like it's been put into syrap as to follow the tray instead. \$\endgroup\$ Nov 28, 2023 at 15:39
  • 1
    \$\begingroup\$ @RichardMuthwill It vastly depends on the game. I've played VR games where the user had to drop an object directly on a space for it to be attached, but if the object dropped there by itself, nothing would happen. Your idea of attaching the object to the tray only once the object is mostly still would also work. My suggestion would be to implement the method that takes the least amount of work/time, and in the future if it doesn't suit your game, update it. \$\endgroup\$ Nov 28, 2023 at 15:59
1
\$\begingroup\$

I have found a suitable solution using both Unity's built-in materials and a script that uses a trigger as a parent modifier.

Both the tray's and mug's collider has a material attached that raises friction. Unity maximum friction material

I then have a trigger collider that is the same size as the tray but ever so slightly larger on all sides compared to the physical collider.

Unity trigger collider

This is used by a script that parents this object of it is close enough.

using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;

public class RigidbodySurface : MonoBehaviour
{
    void OnTriggerEnter(Collider col)
    {
        if (col.GetComponent<XRGrabInteractable>() != null) {
            col.transform.parent = transform;
        }
    }

    void OnTriggerExit(Collider col)
    {
        if (col.GetComponent<XRGrabInteractable>() != null)
        {
            col.transform.parent = null;
        }
    }
}

I found tips by remembering this is just like having a character or object on a moving platform in a platformer game. Leaving this description for future reference in case someone is searching for a way to have a moving platform in a puzzle game where objects need to follow the platform, like the player.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .