# Hand

The core component of Auto Hand. This will manage Grabbing, Highlighting, Posing, and Movement. Requires a rigidbody. This component should be added to the root of your hand model, which should contain the rigged skeleton and the skinned mesh rendered underneath it

<figure><img src="https://2959669391-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F5zKO0EvOjzUDeT2aiFk3%2Fuploads%2FwHKWbGvHNNQOiTTrLerj%2Fimage.png?alt=media&#x26;token=b88bcec2-e67c-4e17-b5e9-44e9cd98c730" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2959669391-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F5zKO0EvOjzUDeT2aiFk3%2Fuploads%2F4tcIfeKNGv5putROPqQR%2Fimage.png?alt=media&#x26;token=5dd41254-fd12-4645-b875-388a49d64895" alt=""><figcaption></figcaption></figure>

## Core Settings

The hand requires **`finger`** components and a **`palm transform`** to generate poses

<figure><img src="https://2959669391-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F5zKO0EvOjzUDeT2aiFk3%2Fuploads%2FX6V4ep8bIqCNAkjDsljj%2Fimage.png?alt=media&#x26;token=11e26550-3dbc-4dc4-9e72-656a092ac76b" alt=""><figcaption></figcaption></figure>

### Finger

Each knuckle on the skeleton should have a `finger` component. The finger requires a transform that represents the finger tip and tip radius (which will act as a bumper for automatic grabbing)

The fingers must be connected before the open/closed poses can be saved

{% content-ref url="hand/finger-component" %}
[finger-component](https://earnest-robot.gitbook.io/auto-hand-docs/auto-hand/hand/finger-component)
{% endcontent-ref %}

### **Palm Transform**

The palm transform represents the point and forward direction of the grab. This will affect where the automatic grab will be positioned in the hand and where the cone that looks for grab targets is projected from.&#x20;

This should be an empty transform placed at the center of the palm, with the LOCAL forward rotation (blue arrow) facing away from the hand

![](https://2959669391-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F5zKO0EvOjzUDeT2aiFk3%2Fuploads%2FWBpYGSQsvyEnBH1h3ZLw%2Fimage.png?alt=media\&token=d827c4e1-549c-4520-9b8f-116e3a8c4d9e)

## **Movement**

<figure><img src="https://2959669391-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F5zKO0EvOjzUDeT2aiFk3%2Fuploads%2FxVV98oXYFPAjLfrIo1S0%2Fimage.png?alt=media&#x26;token=3f1827cd-9366-449e-829d-8abd007c50e7" alt=""><figcaption></figcaption></figure>

The hand will `follow` the given transform and match it's position/rotation using rigidbody forces

You can disable movement by disabling this `Enable Movement` toggle, or setting the rigidbody to be kinematic

The hand will teleport to the follow position if it's distance from the follow target is greater than the max follow distance. If the hand is holding a grabbable during teleport it will release or bring the held object based on the grabbable's "parent on grab" value

`Follow` represents the transform that the hand will use physics movement to try and match

* (Recommend making the follow an empty transform under the controller, which can be used to offset the hands position/rotation)

`Throw Power` multiplies the velocity of the grabbable on release by this value

`Gentle Grab Speed` multiplies the controller movement required to return the object if the grabbable's gentle grab value is enabled

{% content-ref url="hand/hand-follow" %}
[hand-follow](https://earnest-robot.gitbook.io/auto-hand-docs/auto-hand/hand/hand-follow)
{% endcontent-ref %}

## Posing

<figure><img src="https://2959669391-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F5zKO0EvOjzUDeT2aiFk3%2Fuploads%2FIvATGoU9It1S2Bxri3WD%2Fimage.png?alt=media&#x26;token=f28b9b0e-586a-43f7-a1aa-e921ad72b6e1" alt=""><figcaption></figcaption></figure>

Disable this module when doing custom animations. The posing module will update the fingers, create finger sway, and look for custom pose areas. The Grab/AutoPose functions will still perform poses.

`Sway Strength` will be how much the fingers sway when the hands moves, 0 to disable

`Grip Offset` will offset the bend of every finger. 0.14 is slight bend 1 is full bend

{% hint style="info" %}
Automatic posing is default when grabbing a [Grabbable ](https://earnest-robot.gitbook.io/auto-hand-docs/auto-hand/grabbable)without any custom pose components

Learn more: [✍Custom Poses](https://app.gitbook.com/s/5zKO0EvOjzUDeT2aiFk3/auto-hand/custom-grab-poses)
{% endhint %}

{% content-ref url="hand/hand-animator" %}
[hand-animator](https://earnest-robot.gitbook.io/auto-hand-docs/auto-hand/hand/hand-animator)
{% endcontent-ref %}

## Highlighting

<figure><img src="https://2959669391-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F5zKO0EvOjzUDeT2aiFk3%2Fuploads%2FwwrcUX0ftg62rS8gLYaI%2Fimage.png?alt=media&#x26;token=8ab6a5e6-e7e0-408b-8097-0c3dbbc19d0c" alt=""><figcaption></figcaption></figure>

The highlighting module will look for grabbables to highlight. This is a passive system should be disabled for optimization purposes when not being used. If Highlight layers are left on nothing, it will default to grabbable, so make sure to disable the Enable Highlight toggle instead.

Highlighting events are triggered when an object is being targeted for grabbing

`Highlight Layers` represents which layers the highlight module will search for, (will default to grabbable if left blank to disable highlighting uncheck `Enable Highlight`)

`Default Highlight` material will be applied to all grabbables without a highlight material

* Highlight Material works by making a copy of the target grabbable's mesh, applying the highlighted material, and scaling it up slightly

{% content-ref url="hand/grabbable-highlighter" %}
[grabbable-highlighter](https://earnest-robot.gitbook.io/auto-hand-docs/auto-hand/hand/grabbable-highlighter)
{% endcontent-ref %}

## Advanced Options

<figure><img src="https://2959669391-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F5zKO0EvOjzUDeT2aiFk3%2Fuploads%2F6cNx8zvKeUNwDpzNY6UX%2Fimage.png?alt=media&#x26;token=34946cb9-2cd7-4027-8672-497ef930625e" alt=""><figcaption></figcaption></figure>

* `Grab Type` decides whether the hand grabs objects, objects move to hands, or are instant grab
* `Min Grab Time`&#x20;
* `Max Grab Time`&#x20;
* `Grab Curve` represents the animation over the grab time of the grab
  * (x = grab time from 0-1, y = grab pose from 0-1)
* `Pose index` must match the pose index of pose components to work (added for supporting more than one hand model per game)

## Events

While the Auto Hand includes internal C# Events, public Unity Events can be found through the **Hand Public Events** component

<div align="left"><img src="https://2959669391-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F5zKO0EvOjzUDeT2aiFk3%2Fuploads%2FP9FGlcgNWsjfhZoV52B8%2Fimage.png?alt=media&#x26;token=a9dfa0cf-55a5-495a-ad8a-35169f5f1bad" alt=""></div>

* `On Before Grab` is called after a grab is confirmed possible, before the grab has started
* `On Grab` is called when the hand touches the grabbable, after the grab connection is made
* `On Release` is called when the hand releases the grabbable
* `On Force Release` is called when the force release function is called forcing the object to be “dropped” instead of properly released
* `On Squeeze` called on when the squeeze button is trigger while holding a grabbable. Squeeze button is determined by the `Hand Controller Link` settings (attached to “Input” gameobject under hands in demo)

## **Controller Input**

{% content-ref url="controller-input/hand-input" %}
[hand-input](https://earnest-robot.gitbook.io/auto-hand-docs/auto-hand/controller-input/hand-input)
{% endcontent-ref %}

## Haptic Collisions

An optional component that can be added to the Hand object is the `Hand Collision Haptics` this component will cause controller vibrations (if supported by input system) when the hands collide with objects on the collision triggers mask.&#x20;

<div align="left"><img src="https://2959669391-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F5zKO0EvOjzUDeT2aiFk3%2Fuploads%2FLtRIPhfJfrydsZYRvaOn%2Fimage.png?alt=media&#x26;token=92f2505c-7fac-4773-ab47-2d33ee20df6a" alt=""></div>

## Grab Lock

You can add the Grab Lock component onto a Grabbable object to prevent it from being released via the usual Hand.Release() method. Instead you will have to call the Hand.ForceRelease() or Hand.ReleaseGrabLock() method to drop an grabbable with this component.&#x20;

\You can also enabled/disable the grablock using grablock.enabled to toggle through script

## **Distance Grabbing**

{% content-ref url="grabbable/distance-grabbing" %}
[distance-grabbing](https://earnest-robot.gitbook.io/auto-hand-docs/auto-hand/grabbable/distance-grabbing)
{% endcontent-ref %}

## **Hand Projection**

{% content-ref url="hand/hand-projector" %}
[hand-projector](https://earnest-robot.gitbook.io/auto-hand-docs/auto-hand/hand/hand-projector)
{% endcontent-ref %}

## **Programming Info**

Auto Hand hands have four essential functions, `Grab()`, `Release()`, `Squeeze()`, and `Unsqueeze()`

#### Grabbing

> Grabbing is best done with the default `Grab()` function, but grabbing only what is in front of the hand does not fit every use case. While the `Grab()` functions are most consistent, if you do not have a meaning of getting a proper raycasthit you can use the `TryGrab()` function instead

```csharp
//Will grab whatever is in front of and closest to the hands palm
hand.Grab()

//Will grab the grabbable target given a raycast hit
hand.Grab(RaycastHit hit, Grabbable target)

//Will try to automatically create a useable raycast hit to do a grab with just a target
hand.TryGrab(Grabbable target)

//(Good for syncing grabs over a network) 
//Will forcably create a grab connection using the given values without creating an Auto Pose
hand.CreateGrabConnection(Grabbable grab, Vector3 handPos, Quaternion handRot, Vector3 grabPos, Quaternion grabRot, bool executeGrabEvents = false)
```

#### Releasing

> The `Release()` function will release whatever the hand is currently holding and apply the hands velocity and throw power to the grabbable. `ForceRelease()` will release the grabbable without applying throw force. Both will call the `OnReleaseEvent`

```csharp
//Will release the hand and add hand throw velocity
hand.Release();

//Will release the hands object without applying throw (like it was dropped)
hand.ForceRelease();
```

#### Squeezing

> The `Squeeze()` function is used to call an additional event on the grabbable and hand through controller input while held

```csharp
//Will trigger squeeze event on the hand and held grabbable
hand.Squeeze();

//Will trigger unsqueeze event on the hand and held grabbable
hand.Unsqueeze();
```

#### Haptics

> Auto Hand haptics supported for if supported by your device for that system

```csharp
//Will play haptic on the hand if supported by input system and device
hand.PlayHapticVibration()
hand.PlayHapticVibration(float duration)
hand.PlayHapticVibration(float duration, float amp)
```

#### Auto Posing Function

> Advanced users might want to use just the Auto Pose generation in their system. In order to do so you must get a raycast hit point on the surface of your grab target

```csharp
//This will generate and set the hand model as a grab pose based on a raycast hit and grabbabe
//THIS WILL NOT CREATE GRAB CONNECTIONS OR CALL GRAB EVENTS
hand.AutoPose(RaycastHit hit, Grabbable grabbable)
```

#### Set Location

> You can use the `hand.SetLocation(Vector3 position, Quaternion rotation)` to set the hand position/rotation. If the hand is holding a grabbable during this function call it will release or bring the held object based on the whether or not the grabbable's "parent on grab" is true

```csharp
//Will set the hands position/rotatation
hand.SetLocation(Vector3 position, Quaternion rotation) 
```

For more advanced information on internal settings and custom layer options, see

## Programming Events

```csharp
using UnityEngine;
using Autohand;

public class HandEventTemplate : MonoBehaviour{
    public Hand hand;

    void OnEnable() {
        hand.OnBeforeGrabbed += OnBeforeGrabbed;
        hand.OnGrabbed += OnGrabbed;
        hand.OnBeforeReleased += OnBeforeReleased;
        hand.OnReleased += OnReleased;
        hand.OnForcedRelease += OnForcedRelease;
        hand.OnGrabJointBreak += OnGrabJointBreak;

        hand.OnHandCollisionStart += OnHandCollisionStart;
        hand.OnHandCollisionStop += OnHandCollisionStop;
        hand.OnHandTriggerStart += OnHandTriggerStart;
        hand.OnHandTriggerStop += OnHandTriggerStop;

        hand.OnHighlight += OnHighlight;
        hand.OnStopHighlight += OnStopHighlight;

        hand.OnSqueezed += OnSqueezed;
        hand.OnUnsqueezed += OnUnsqueezed;

        hand.OnTriggerGrab += OnTriggerGrab;
        hand.OnTriggerRelease += OnTriggerRelease;
    }

    void OnDisable() {
        hand.OnBeforeGrabbed -= OnBeforeGrabbed;
        hand.OnGrabbed -= OnGrabbed;
        hand.OnBeforeReleased -= OnBeforeReleased;
        hand.OnReleased -= OnReleased;
        hand.OnForcedRelease -= OnForcedRelease;
        hand.OnGrabJointBreak -= OnGrabJointBreak;

        hand.OnHighlight -= OnHighlight;
        hand.OnStopHighlight -= OnStopHighlight;

        hand.OnSqueezed -= OnSqueezed;
        hand.OnUnsqueezed -= OnUnsqueezed;

        hand.OnTriggerGrab -= OnTriggerGrab;
        hand.OnTriggerRelease -= OnTriggerRelease;

        hand.OnHandCollisionStart -= OnHandCollisionStart;
        hand.OnHandCollisionStop -= OnHandCollisionStop;
        hand.OnHandTriggerStart -= OnHandTriggerStart;
        hand.OnHandTriggerStop -= OnHandTriggerStop;
    }

    void OnBeforeGrabbed(Hand hand, Grabbable grab) {
        //Called when an object is grabbed before anything else
    }

    void OnGrabbed(Hand hand, Grabbable grab) {
        //Called when an object is grabbed
    }

    void OnBeforeReleased(Hand hand, Grabbable grab) {
        //Called when a held object is released before anything else
    }

    void OnReleased(Hand hand, Grabbable grab) {
        //Called when a held object is released
    }

    void OnForcedRelease(Hand hand, Grabbable grab) {
        //Called when the force release functions is called

    }

    void OnGrabJointBreak(Hand hand, Grabbable grab) {
        //Called when the joint between the hand the grabbable breaks
    }

    void OnHighlight(Hand hand, Grabbable grab) {
        //Called when the hand grab targets a new object
    }
    
    void OnStopHighlight(Hand hand, Grabbable grab) {
        //Called when the hand grab stops targeting an object
    }

    void OnSqueezed(Hand hand, Grabbable grab) {
        //Called when the "Squeeze" event is called, this event is tied to a secondary controller input through the HandControllerLink component on the hand
    }
    void OnUnsqueezed(Hand hand, Grabbable grab) {
        //Called when the "Unsqueeze" event is called, this event is tied to a secondary controller input through the HandControllerLink component on the hand
    }

    void OnTriggerGrab(Hand hand, Grabbable grab) {
        //Called when the "Grab" event is called, regardless of whether something is being grabbed or not
    }
    void OnTriggerRelease(Hand hand, Grabbable grab) {
        //Called when the "Release" event is called, regardless of whether something is being held or released
    }

    void OnHandCollisionStart(Hand hand, GameObject other) {
        //Called when the hand hits an object for the first time and isn't already colliding
    }

    void OnHandCollisionStop(Hand hand, GameObject other) {
        //Called all the hand has zero collisions on the object

    }

    void OnHandTriggerStart(Hand hand, GameObject other) {
        //Called when the hand triggers an object for the first time and isn't already triggering
    }

    void OnHandTriggerStop(Hand hand, GameObject other) {
        //Called when the hand has zero colliders overlapping this trigger
    }

}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://earnest-robot.gitbook.io/auto-hand-docs/auto-hand/hand.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
