Extending Hand Interaction: Grab and Release

Get started on making your own Meta 2 app today!

Extending Hand Interaction: Grab and Release

16

NOV 
2017
BY Joseph Leybovich & Jacqueline Luke

We have created a quick tutorial on extending hand interaction to customize drag and release functionality with our very own software developer, Joseph Leybovich. This is a fun and easy way to get started on creating your own app in just 15 minutes. Make sure to follow along as we’ll have more tutorials in the future. Happy developing!

joetutorialteaser-1.gif

Snippet from tutorial video.

Scene Setup:

First thing you should notice is that we have our MetaCameraRig and MetaHands prefabed gameobjects in the scene. The Meta camera rig has a few under it so we do not need a separate Main Camera for this tutorial.

MetaCameraRig-1.png

MetaCameraRig screengrab from video tutorial.

MetaHands.png

MetaHands screengrab from video tutorial.

There are 3 spheres in the hierarchy that have several effects under them and a script called CloneGrab which will be the main focus of this example. They also have a collider which is needed for objects that utilize Interaction components to work properly.

 

The clone grab components have a reference to similar prefabs that have the same effects but instead of a CloneGrab component they have an ExplodeAfterDetach component which does not rely on the Meta API.

 

One last thing to note in the scene is the positioning and scale of the 3 spheres. This is important because Meta works under the assumption that things are laid out in real-world meters so the scale of our spheres are at 0.1 and they are positioned rather close to our camera rig with an offset of 0.25 in the X and Z axes. You can play around with the Transforms in your scene but if you find that you cannot interact with your Interaction objects it might be that you need to bring them closer to your camera rig. Or if your objects appear too large you might need to scale them down. You will know that the hand is being registered as being over the object by an indicator that will appear on your hand. When in doubt use the example scenes as reference.

Screen Shot 2017-11-07 at 2.43.12 PM.png

CloneGrab:

CloneGrab derives off of Interaction which is provided with the Meta SDK and is the base class for the different ways to respond to Hand interaction. Some other Interaction provided by the SDK are GrabInteraction, TwoHandGrabRotateInteraction, and many more.

 

What we are gonna do with our custom interaction is create a clone of our projectiles when the grab has engaged and add a forward velocity to our projectile when released.

Let’s look at the code:

Copyright © 2017, Meta Company.  All rights reserved.

Redistribution and use of this software (the "Software") in source and binary forms, with or without modification, is permitted provided that the following conditions are met:

1. Redistributions in source code must retain the above copyright notice, this list ofconditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. The name of Meta Company (“Meta”) may not be used to endorse or promote products derived from this software without specific prior written permission from Meta.

4. LIMITATION TO META PLATFORM: Use of the Software and of any and all libraries (or other software) incorporating the Software (in source or binary form) is limited to use on or in connection with Meta-branded devices or Meta-branded software development kits. For example, a bona fide recipient of the Software may modify and incorporate the Software into an application limited to use on or in connection with a Meta-branded device, while he or she may not incorporate the Software into an application designed or offered for use on a non-Meta-branded device.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL META COMPANY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

using Meta;

using Meta.HandInput;

using UnityEngine;

 

public class CloneGrab : Interaction

{

[SerializeField] GameObject _prefab;

[SerializeField] private float _speed = 1.0f;

 

private HandFeature _handFeature;

private GameObject _heldGameObject;

 

protected override void Engage()

{

_handFeature = GrabbingHands[0];

if (_heldGameObject == null)

{

_heldGameObject = Instantiate(_prefab);

}

_heldGameObject.transform.position = _handFeature.transform.position;

_heldGameObject.GetComponent<Rigidbody>().velocity = Vector3.zero;

}

 

protected override void Disengage()

{

if (_handFeature == null || _heldGameObject == null)

{

return;

}

var newVec = _handFeature.transform.position - Camera.main.transform.position;

newVec = newVec.normalized * _speed;

_heldGameObject.GetComponent<Rigidbody>().velocity = newVec;

_heldGameObject.SendMessage("Detach");

_heldGameObject = null;

}

 

protected override void Manipulate()

{

if (_handFeature == null || _heldGameObject == null)

{

return;

}

_heldGameObject.transform.position = _handFeature.transform.position;

}

}

Up top we have inspector set fields for the prefab to clone as well as a speed variable. We also have a cache of the HandFeature and GameObject instances we want to manipulate during the grab interaction.

 

Then we override the Engage function which gets called when the grab has began. We retrieve the first GrabbingHand we get from our base class, store it in our member variable and if we do not have a clone yet we instantiate one and store it in the other member variable. Next we set the position of our projectile to the position of the hand feature and set its velocity to zero.

 

When we release the projectile we want it to fly foward, to accomplish this we override the Disengage function. First we check that our member variables are not null because we will need both for a proper release. Then we get a vector from the camera to the hand we are tracking. We normalize the vector to get the direction and multiply it by our speed variable. We then set the velocity of the RigidBody on our projectile to the new vector. Finally we notify the projectile that it has been detached so it can destroy it in the future and set our variable to null so we can create another one on the next grab.

 

The last piece is to override the Manipulate function. This method is called while you are dragging around the object. We check our variables for null and if they are valid we set the projectile's position to the hand position so it moves around with our hand. 

 

For a closer look, please take a look at the video tutorial below.