# Interactions

### Adding Interaction

1. To define custom behavior when interacting with an object, first change the object's layer to <mark style="color:red;">**Interact**</mark> to indicate that the object is interactable.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2Fr4sTrmlxzrJsu2BHR27y%2FScreenshot_1.png?alt=media&#x26;token=d4c30efb-a8e5-4640-af65-331d3afa2d93" alt=""><figcaption></figcaption></figure>

2. Next, to specify the desired actions upon interacting with the object, attach a **Custom Interact Event** component to the object and configure events for when you **Start**, **Hold**, or **Stop** interacting with it.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2FhOLVZJZjM7mTnK2wVumq%2FScreenshot_2.png?alt=media&#x26;token=79f3446f-a826-494f-a270-f0c136300ab0" alt=""><figcaption></figcaption></figure>

3. Alternatively, you can implement an interfaces into your custom script and define unique behaviors without relying on events within the **Custom Interact Event** component.

You can use these types of interfaces to define your own behavior:

* **`IHoverStart`** - The method is called when you hover the mouse over the interactive object.
* **`IHoverEnd`** - The method is called when you stop hovering the mouse over the interactive object.
* **`IInteractStart`** - The method will be called when you start interacting with the object, once.
* **`IInteractHold`** - The method will be called as long as you keep the use button pressed.
* **`IInteractStop`** - The method will be called when you stop interacting with the object, once.
* **`IInteractStartPlayer`** - The method will be called once when you start interacting with the object, but it will receive a parameter containing a reference to the player object.
* **`IStateInteract`** - When you interact with the object, the current state of the player's state machine will be changed based on the parameters used in the **StateParams**.
* **`IInteractTimed`** - You will interact with the object when you hold down the use buttom button for a specified amount of time.
* **`IInteractTitle`** - The title displayed when interacting with the object will be changed based on the parameters used in the **TitleParams**.

You can also implement interfaces that allow you to define custom behavior when you examine an object and that object has interactive elements such as switches, etc. (example: Radio)

* **`IExamineClick`** - The method will be called when you click on the interactive object.
* **`IExamineDragVertical`** - The method will be called when you click and move the mouse in the vertical direction. As an argument, you get the **dragDelta** value.
* **`IExamineDragHorizontal`** - The method will be called when you click and move the mouse in the horizontal direction. As an argument, you get the **dragDelta** value.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2FpWGLXYs5a4Fh366jHJuS%2FScreenshot_1.png?alt=media&#x26;token=65b312cf-80d8-45ac-a233-4080d6645cde" alt=""><figcaption></figcaption></figure>

### Changing Interact Title

1. To change the interact message displayed when you interact with an object, you can add a **Custom Interact Title** component to the object.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2F34Tqm2gj8YEIKoEvrL9I%2FScreenshot_1.png?alt=media&#x26;token=1d6fda46-cfc2-4515-9ce1-aa90f81be021" alt=""><figcaption></figcaption></figure>

2. You can define whether the title **Is Dynamic**, which means it can change dynamically based on the reflected field or property value of the script.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2FODSPIflIsQ3aAorFpVjO%2FScreenshot_5.png?alt=media&#x26;token=d63be439-f3eb-41c0-a676-b3b8bf3a8d01" alt=""><figcaption></figcaption></figure>

{% hint style="danger" %}
The **Reflected Name** variable must be of type <mark style="color:red;">**`Bool`**</mark>, otherwise it will not be able to get a true/false value.
{% endhint %}

{% hint style="info" %}
If a text starts with an **asterisk (\*)**, it will be treated as plain text rather than a key for localization.
{% endhint %}

### Changing Interact Reticle

1. To change the interact reticle when you interact with an object, you can add a **Custom Interact Reticle** component to the object.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2Fwawj9o1NpV3wPLARttzU%2FScreenshot_2.png?alt=media&#x26;token=4e74f977-f703-488d-b0ae-c95757a0f1ee" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
You can override the interact reticle while holding the use button by enabling **Dynamic Hold Reticle** and defining the reflection variable that will determine when to switch to the hold reticle.
{% endhint %}

### Custom IInteractTimed Script

{% hint style="info" %}
When you implement the **IInteractTime** interface in your custom script, you will be needed to modify the interface parameters a little bit.
{% endhint %}

1. At the top of the **InteractTime** parameter, add the `[field: SerializeField]` attribute as following. This converts the property to an field and allows Unity to serialize it and display it in the inspector.

```csharp
[field: SerializeField]
public float InteractTime { get; set; }
```

2. Then just define whether the interaction should be performed or not by setting the **NoInteract** value to **false** or **true**. In my case, I just created a new field that controls the interaction state.

```csharp
public bool CanInteract = true;
public bool NoInteract => !CanInteract;
```

Here is the whole script:

```csharp
using UnityEngine;
using UHFPS.Runtime;

public class TestTimedInteract : MonoBehaviour, IInteractTimed
{
    [field: SerializeField]
    public float InteractTime { get; set; }
    public bool CanInteract = true;

    public bool NoInteract => !CanInteract;

    public void InteractTimed()
    {
        // do something 
    }
}
```
