# Player Items

### Adding New Player Items

1. To add a new player item, locate the **Hands** object inside the **HEROPLAYER** object. Create a new game object in the **Hands** object and name it as you want, but to keep the structure clean, name it, for example: <mark style="background-color:green;">**Flashlight**</mark><mark style="background-color:red;">**Item**</mark>

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2Fe4r0QUMzaVTVrv4UtclH%2FScreenshot_5.png?alt=media&#x26;token=1ab87687-60d3-4579-b792-1cadd9403338" alt=""><figcaption></figcaption></figure>

2. Add your player item model with animations to the newly created player item object and name it, for example: <mark style="background-color:green;">**Flashlight**</mark><mark style="background-color:purple;">**Anims**</mark>.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2Fe5XcuXmST1JC5iTBTJKB%2FScreenshot_7.png?alt=media&#x26;token=f4bffe04-cf4d-471c-b583-c692189056b5" alt=""><figcaption></figcaption></figure>

3. *(optional)* If you want to add a nice sway effect to the item when you move the camera, create a new object inside your newly created item and name it, for example **Pivot,** and position it at the pivot point in the player item model. Then add the item model object to the **Pivot** object, as shown in the image at **Step 1**.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2Fmw3WvmhGAxdAXARW4TaG%2FScreenshot_6.png?alt=media&#x26;token=7989acd2-ca04-4331-aaaa-feded30b8220" alt=""><figcaption></figcaption></figure>

4. If you don't have one, create a new **Animator Controller** asset. Add your item animation states to it and create transitions between them. After creating the **Animator Controller** asset and setting up the animation states and transitions, assign the **Controller** reference in the **Animator** component of the ~~**FlashlightAnims**~~ object.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2F0KkiAdqnAUViYd0YdcOc%2FScreenshot_8.png?alt=media&#x26;token=9967c9d4-92dd-44e3-8922-460b563148dc" alt=""><figcaption></figcaption></figure>

5. To handle all the logic of the player item, create a new script. For this guide, I'll name it ~~**Flashlight**~~ and derive it from the **PlayerItemBehaviour** class.
6. After deriving from the **PlayerItemBehaviour** class, you will be prompted to implement the four main functions that handle when the item is selected or deselected.

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

public class Flashlight : PlayerItemBehaviour
{
    public ItemGuid BatteryItem;

    public override void OnItemSelect()
    {
        // do something when the item is selected
    }
    
    public override void OnItemDeselect()
    {
        // do something when the item is deselected
    }
    
    public override void OnItemActivate()
    {
        // do something when the item is activated
    }
    
    public override void OnItemDeactivate()
    {
        // do something when the item is deactivated
    }
}
```

{% hint style="info" %}
Your script inspector may look messy after deriving from the **PlayerItemBehaviour** class. To achieve a clean look, create a new editor script for your player item script and name it, for example, ~~**FlashlightEditor**~~.
{% endhint %}

* In the editor script, derive from the **PlayerItemEditor** class and override the **OnInspectorGUI()** function to define how your script should look in the inspector. Here is a code snippet for the ~~**FlashlightEditor**~~ script:

```csharp
using UnityEngine;
using UnityEditor;
using ThunderWire.Editors;

namespace UHFPS.Editors
{
    [CustomEditor(typeof(Flashlight))]
    public class FlashlightEditor : PlayerItemEditor<Flashlight>
    {
        public override void OnEnable()
        {
            // when overriding OnEnable(), do not remove the base.OnEnable()
            base.OnEnable();
        }
    
        public override void OnInspectorGUI()
        {
            EditorDrawing.DrawInspectorHeader(new GUIContent("Flashlight"), Target);
            EditorGUILayout.Space();

            serializedObject.Update();
            {
                base.OnInspectorGUI(); // this will draw settings dropdown
                EditorGUILayout.Space();

                Properties.Draw("<ItemObject>k__BackingField");
                Properties.Draw("BatteryItem");
            }
            serializedObject.ApplyModifiedProperties();
        }
    }
}
```

{% hint style="danger" %}
Make sure to put the editor script in the **Editor** folder, otherwise you won't be able to find some editor class references.
{% endhint %}

{% hint style="info" %}
You can use ***Properties.Draw("property name")*** to easily draw your player item script properties. Note that a reference to **Properties** is only available when you derive from **PlayerItemEditor** or **MonoBehaviourEditor**.
{% endhint %}

{% hint style="info" %}
If you're unsure how to write editor scripts, you can take a look at the editor scripts that come with the asset for player items. They can be found at **Scripts\Editor\Runtime\PlayerItems**.
{% endhint %}

7. Add the ~~**Flashlight**~~ script to the ~~**Flashlight**~~ object and set the **Item Object** reference to the ~~**FlashlightAnims**~~ object where the Animator is located.
8. *(optional)* To enable the **Item Motions**, simply enable the **Motion Preset** feature and assign the **Motion Preset** and **Motion Pivot**. You can also leave the Motion Pivot object unassigned if you want to use the default camera pivot object.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2FuwtGbjaXKVNwppj7NMgU%2FScreenshot_11.png?alt=media&#x26;token=58989c1a-10ad-4dd9-93f1-af13effd01eb" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
To enable wall detection, you can toggle the **Wall Detection** feature. This will prevent the player item from clipping through walls or other objects by hiding it when you come close to them.
{% endhint %}

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2FLogXAT0awmYchDuJJlxt%2FScreenshot_9.png?alt=media&#x26;token=2cb9969a-fc45-42fd-a1f8-a312892b3121" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2F8nqRVtuPs4OLlpGjaeRK%2FScreenshot_1.png?alt=media&#x26;token=dc87e952-16b6-4926-be61-1b1301738b25" alt=""><figcaption></figcaption></figure>

7. Add your newly created player item to the **Player Items Manager** component in **FPView** inside the **HEROPLAYER** object.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2FrMhQHATSRFSFQ3IJO4X4%2FScreenshot_9.png?alt=media&#x26;token=77bd5b9f-c6d9-495d-8f6a-04952a44ce1c" alt=""><figcaption></figcaption></figure>

8. To make an item equippable, you can open the inventory builder and enable the **Is Usable** setting. After that, set the **Usable Type** to **Player Item** and assign the **Player Item** reference.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2Fr1CgAlLmxzTNuH6JRkrh%2FScreenshot_3.png?alt=media&#x26;token=f3d9bdb8-28df-4600-b022-d5a55ece85ca" alt=""><figcaption></figcaption></figure>

### External Motions

{% hint style="info" %}
When using a player item, you can define external camera movements to create a realistic camera wobble effect.
{% endhint %}

1. To enable external motions, go to the player item script and enable **Camera Motions**.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2FiamyMQl7ojIdMbucHdZY%2FScreenshot_7.png?alt=media&#x26;token=be71ea2e-8abb-4781-8f60-5f948e0ffb00" alt=""><figcaption></figcaption></figure>

2. Add external motion states and define a custom **Event ID** that will be used to identify the state to be played from the player item script.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2FXqZtJsAYvpnPXdSwN1bj%2FScreenshot_8.png?alt=media&#x26;token=c6e18944-187e-430b-a6d5-c9b4a1de65bd" alt=""><figcaption></figcaption></figure>

3. Add motion modules to the motion state. Currently there are only a few, but you can create your own modules very easily.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2FAOwzSdp9ukNQMX0eHm1m%2FScreenshot_9.png?alt=media&#x26;token=4b9534ec-6293-4797-b780-7c380389b624" alt=""><figcaption></figcaption></figure>

{% content-ref url="motion-controller/external-motions" %}
[external-motions](https://docs.twgamesdev.com/uhfps/guides/motion-controller/external-motions)
{% endcontent-ref %}

4. Finally, you can apply external motions by calling the **ApplyEffect()** method in the **Player Item** script, which inherits from **PlayerItemBehaviour**.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2Fi9xgVYD02SMjlFNS1yho%2FScreenshot_10.png?alt=media&#x26;token=d94c4ea4-bd60-4070-84ca-13f63adcfcf9" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
You can also adjust the settings of the base **External Motion** module, which applies motions directly to the camera in the **MotionController** component in the **Default** state.
{% endhint %}

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2F9ihfEyejZDnRYNqgtRDQ%2FScreenshot_11.png?alt=media&#x26;token=fdeafbda-753a-47b1-801c-a2115a0fadc0" alt=""><figcaption></figcaption></figure>
