Skip to content

Create Custom Grab Mechanics⚓︎

Grabbing in VR can have a vast meaning and mechanics. The grabbing in massive loop allows the developer to create their custom grab mechanics that fits their purpose.

Here, we discuss on how to create a custom grab mechanics using the MLGrab Component and using the MLGrab API.

The component⚓︎

To create a custom grab mechanics, we need the MLGrab component attached to our grabbable object. This component creates the necessary interfaces for players hand to recognize the object as grabbable and perform the grabbing actions, as well as detecting the trigger actions.

To begin, we need to set the Grab Mechanics property of the MLGrab to Custom. When this property set to custom, the MLGrab will still makes the object grabbable and detects and send the event related to grabbing the event, but it will not move (apply grab mechanics) to the object. This is where the developers can define their custom mechanics.

The API⚓︎

To define the custom mechanics, we need to use Lua script.

  1. Add a new Lua script to the same object.
  2. Create a serialized field called GrabComponent with type of MLGrab.
do
    local customGrab = LUA.script;

    local grabComponent = SerializedField("GrabComponent", MLGrab);
end
  1. Drag and drop the MLGrab component to the field in the Lua script.

Now that we have the access to the MLGrab Component, we can use the MLGrab api to create our custom grab mechanics.

Grab Mechanics⚓︎

First, we need to know when an object is grabbed by player. On the start function,

  1. Create a local variable which we set to true when player grabs the object.

  2. Attach event handlers to the grab component to know when the object is grabbed or released by the player.

do
    local customGrab = LUA.script;

    local grabComponent = SerializedField("GrabComponent", MLGrab);

    local isGrabbed = false;

    local function primaryGrabBegin()
        isGrabbed = true;
    end

    local function primaryGrabEnd()
       isGrabbed = false; 
    end

    function customGrab.Start()
       if grabComponent ~= nil then
            grabComponent.OnPrimaryGrabBegin.Add(primaryGrabBegin);
            grabComponent.OnPrimaryGrabEnd.Add(primaryGrabEnd);
       end
    end

end

now that we registered the events for when the player grabs or releases the object, we can work on the actual mechanics of the grabbing.

What is grab mechanics?⚓︎

The grab mechanics mentioned a lot here, but what does it mean?

The grab mechanics means moving, applying force or apply other necessary modifications in order to grabbing have an actual effect on the object.

What in the object needs to be changes for the grab mechanics?⚓︎

There is no limit on what effect on object can be constitutes a grab mechanics and it is purely depending on the outcome, but here are few examples:

  1. Moving the object. The Most common thing is to move the object. For most grabs, the objects position and rotation will be affected by the players hand position. This is how the default grab mechanics works.
  2. Applying force to the object.
  3. Changing animations on object.
  4. Combination of few things, again there is no limit.

The MLGrab component API provides different information which will may needed to perform any required calculations.

  1. grab.PrimaryHand Transform of the primary1 hand. You can get the players primary hands position and rotation from this.
  2. grab.SecondaryHand Transform of the secondary2 hand. You can get the players secondary hands position and rotation from this.
  3. grab.PrimaryGrabPoint Transform of the Primary Grab Point. You can get both global and local position or rotation of the grab point which is used to grab object.
  4. grab.SecondaryGrabPoint Transform of the Secondary Grab point. You can get both global and local position or rotation of the grab point which is used to grab object by second hand.
  5. grab.ExpectedObjectPosition This is the pre-calculated position where the object should be if the object was using Default grab mode. The calculations factor the hand position and rotations and which hand is currently grabbed the object.
  6. grab.ExpectedObjectRotation This is the pre-calculated rotation where the object should be if the object was using Default grab mode. The calculations factor the hand position and rotations and which hand is currently grabbed the object.

We can re-create the default grab mechanics by setting the object position to ExpectedObjectPosition and rotation to ExpectedObjectRotation in the **LateUpdate ** while the object is grabbed.

do
    local customGrab = LUA.script;

    local grabComponent = SerializedField("GrabComponent", MLGrab);

    local isGrabbed = false;

    local function primaryGrabBegin()
        isGrabbed = true;
    end

    local function primaryGrabEnd()
       isGrabbed = false; 
    end

    function customGrab.Start()
       if grabComponent ~= nil then
            grabComponent.OnPrimaryGrabBegin.Add(primaryGrabBegin);
            grabComponent.OnPrimaryGrabEnd.Add(primaryGrabEnd);
       end
    end

    function customGrab.LateUpdate()
       if isGrabbed then
            customGrab.gameObject.transform.position = grabComponent.ExpectedObjectPosition;
            customGrab.gameObject.transform.rotation = grabComponent.ExpectedObjectRotation;
       end
    end
end

Again, there is no limit on what the grab mechanics can or should do.


  1. The primary hand in a dual grabbing context is the first hand that grabs the object. 

  2. The Secondary hand in dual grabbing context is the second hand which grabs the object. Note that the secondary hand will not always engaged with the object. Or even, an object might not define secondary grab point or a player may not chose to grab an object by two hand.