Grab a cube with two fingers

Hi everyone! I’m doing some stuff on my project and want to implement a pick-up feature with hand. I use Quaternion.Slerp to reach desired positions as below:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ThumbMotion : MonoBehaviour
{
    [SerializeField] private float speed = 0.5f;
    [SerializeField] private Vector3 current_pose;
    private Vector3 power_pose;
    private Vector3 lat_pose;
    private Vector3 pinch_pose;
    [SerializeField] private Text textElement;

    private void Start()
    {
        power_pose = new Vector3(323.2f, 184.9f, 196.2f);
        lat_pose = new Vector3(36.98634f, 219.7511f, 263.6031f);
        pinch_pose = new Vector3(3.885486f, 182.8034f, 184.4494f);
    }

    void Update()
    {
        current_pose = new Vector3(transform.eulerAngles.x, transform.eulerAngles.y, transform.eulerAngles.z);
        Debug.Log(current_pose);
        if (Input.GetKey(KeyCode.L))
        {
            transform.rotation = Quaternion.Slerp(Quaternion.Euler(current_pose), Quaternion.Euler(lat_pose), speed * Time.deltaTime);
            textElement.text = "Lateral";
        }
        else if (Input.GetKey(KeyCode.P))
        {
            transform.rotation = Quaternion.Slerp(Quaternion.Euler(current_pose), Quaternion.Euler(power_pose), speed * Time.deltaTime);
            textElement.text = "Power";
        }
        else if (Input.GetKey(KeyCode.I))
        {
            transform.rotation = Quaternion.Slerp(Quaternion.Euler(current_pose), Quaternion.Euler(pinch_pose), speed * Time.deltaTime);
            textElement.text = "Pinch";
        }
    }
}

However, when I try to pick up a cube, it’s slipping out of my fingers. Could you give and advice on it? I need to have real-world physics on that cube so that when I push it with only 1 finger it will slide on the table. But when I touch a cube from both sides (thumb and index fingers for pinch) I should grab it as in real life. This is not a VR project by the way.

I’m also not sure whether it’s a good idea to use Quaternion.Slerp for that. But generally, I need to move my fingers to specific positions which I will set manually in script. I tried to inspect this project GitHub - Unity-Technologies/articulations-robot-demo, where they implemented the same thing, but only with an articulation body. The problem is that there is not much information about articulation body rotation to a specific point, that is why I didn’t succeed in implementing the same feature in my script. But generally, in their case robot arm grasps the cube, exactly as I want to integrate into my project. I will appreciate any help and advice. Thanks in advance!

Try with more friction

Using the articulations robot demo is exactly what you should go for. Can you be more specific on the shortcomings of the robot demo for you?

More specifically: GitHub - Unity-Technologies/articulations-robot-demo

I tried to integrate these features from this script, but it seems there is not much info on how to rotate the articulation body. In their case, they’re using drive along the z-axis. In my case, I need to rotate my object in local transform.

Unfortunately you won’t make this kind of physics work by modifying the transforms directly. By setting the rotation property of the transform, you’re “teleporting” an object into a new position which will probably either penetrate the object you’re trying to grab or be “just not enough” and slip out of it.

From your script I assume you have some kind of object that represents a thumb and you put it into some positions you’re slerping in between. After you’ve closed the thumb (and thus “grabbing” the object), I assume you’re moving the hand up, also by modifying the transform directly.

If that is the case, this will also not work. The hand is just being teleported frame by frame. It looks like it has a velocity for your eye, but the physics engine knows nothing about it.

Depending on what you’re actually trying to do, you can also just make the cube a child of the hand and remove its rigidbody (that I assume it has one from your original post). You can then continue modifying the transform to your liking because the physics engine is not involved in the movement.

But the thing is that I want to have the same behaviour for all objects. It doesn’t matter cube or a sphere, I just want to lift it with two of my fingers. Yes, I did modifications in the Transform tab. My question is which function to use to rotate my fingers so they will consider physics? Also, my hand should grab any object if it is pressed on both sides by my fingers.

I completely understand what you are trying to achieve. Unfortunately, I highly doubt that you will be successful by modifying transforms of the finger because it overrides the physics behavior.

But let’s try anyways. If you don’t already have a rigidbody on the hand gameobject, add one. Approximate the fingers using capsule colliders. Set isKinematic to true. Adjust your hand so it definitely grabs the target object. Use rigidbody.MovePosition() to move the hand up.

I made a test scene for you to try. Just import on a new project. Use left/right to grab, up/down to lift.

I think however, this doesn’t work nicely. The cube get’s lost if the grip is too tight and all in all it feels a bit janky, but it does work (which I honestly did not expect).

Another way you can do this is to actually create a articulation hierarchy with a Revolute Joint for the thumb and set the target to whatever makes the hand close.

You then also create a rigidbody (isKinematic = true), completely apart from the hand and use a fixed joint to attach the hand articulation hierarchy to the rigidbody. You can now move and rotate the rigidbody as a proxy which rotates and translates the hand.

8206557–1070979–grab_and_move.unitypackage (4.35 KB)

Thanks a lot. I also tried to implement the lifting feature by using an articulation body. As far as I understood we can’t control transform when it’s applied. For this case, it’s required to use target and target velocity. It worked to my surprise) Anyways, thanks for your engagement!

1 Like