> For the complete documentation index, see [llms.txt](https://renownedgames.gitbook.io/ai-tree/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://renownedgames.gitbook.io/ai-tree/api/user-scripting/custom-key.md).

# Custom Key

Instruction to create custom user key

In the AI Tree you can easily create your own task by using scripting API. In this page we will show how you can do it.

{% hint style="success" %}
In this context, we believe that you have already read the previous pages of [**User Scripting**](/ai-tree/api/user-scripting.md) section.
{% endhint %}

In the previous section, we created a task for the platform moving. Let's create unique key for defining point A, B and speed.

Create new script and call it **PlatformKey**, after creation open it script in you scripts editor tool.

> &#x20;**Create -> MonoBehaviour Script**

<figure><img src="https://2203000093-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FGOxTM7Aj9oiVaIINrEkE%2Fuploads%2FrR95JzPXwkwB0Cxs1KRy%2Fimage.png?alt=media&amp;token=69d93c71-b661-4b33-a207-f402ea627a15" alt="" width="563"><figcaption><p>PlatformKey script in project window</p></figcaption></figure>

***

Default Unity MonoBehaviour script template.&#x20;

```csharp
using UnityEngine;

public class PlatformKey : MonoBehaviour
{
    // Start is called once before the first execution of Update 
    // after the MonoBehaviour is created
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
```

***

First of all we need to decide what we will define as key. Let's create new struct **PlatformData**. Don't forget to add `[Serializable]` attribute for custom types.

```csharp
using UnityEngine;
using System;

[Serializable]
public struct PlatformData
{
    public Vector3 pointA;
    public Vector3 pointB;
    public float speed;
}

public class PlatformKey : MonoBehaviour
{
    // Start is called once before the first execution of Update 
    // after the MonoBehaviour is created
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
```

***

Now we are ready to define our **PlatformData** key. We need to change the **PlatformKey** class.

* Remove all methods.
* Change `MonoBehaviour` parent class to `Key<PlatformData>`

```csharp
using RenownedGames.AITree;
using System;
using UnityEngine;

[Serializable]
public struct PlatformData
{
    public Vector3 pointA;
    public Vector3 pointB;
    public float speed;
}

public class PlatformKey : Key<PlatformData> { }
```

{% hint style="success" %}
Done. It's all required steps to define your our key in AITree. Any other type can be used instead of the **PlatformData** type.
{% endhint %}

***

Now we can update **MovePlatformTask** class.

```csharp
using RenownedGames.AITree;
using UnityEngine;

[NodeContent("Move Platform", "Tasks/Custom/MovePlatformTask")]
public class MovePlatformTask : TaskNode
{
    [SerializeField]
    private PlatformKey platformKey;

    private Transform transform;
    private Vector3 destination;

    protected override void OnInitialize()
    {
        base.OnInitialize();
        transform = GetOwner().transform;
        destination = platformKey.GetValue().pointB;
    }

    protected override void OnEntry()
    {
        base.OnEntry();

        PlatformData data = platformKey.GetValue();
        if(destination == data.pointA)
        {
            destination = data.pointB;
        }
        else
        {
            destination = data.pointA;
        }
    }

    protected override State OnUpdate()
    {
        if(Vector3.Distance(transform.position, destination) > 0.1f)
        {
            float speed = platformKey.GetValue().speed;
            transform.position = Vector3.MoveTowards(transform.position, destination, speed * Time.deltaTime);
            return State.Running;
        }
        return State.Success;
    }
}
```

<figure><img src="https://2203000093-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FGOxTM7Aj9oiVaIINrEkE%2Fuploads%2FtR9EULlHmX9UQRZBGrDF%2FImage.png?alt=media&amp;token=56a145c5-56ab-4995-a96c-fceff54fd809" alt="" width="539"><figcaption><p>Platform key in Inspector window</p></figcaption></figure>

***

We can improve displaying of **PlatformKey** in editor. For that we will use [**Apex**](https://assetstore.unity.com/packages/slug/183345) library what included in AITree out of box.&#x20;

{% hint style="info" %}
All editor classes, tasks, keys, decorators, components in AI Tree powered by Apex.
{% endhint %}

Open **PlatformKey** class add following attributes on field of PlatformData struct.

```csharp
using RenownedGames.AITree;
using RenownedGames.Apex;
using System;
using UnityEngine;

[Serializable]
public struct PlatformData
{
    [HideLabel]
    public Vector3 pointA;

    [HideLabel]
    public Vector3 pointB;

    [LabelWidth(100)]
    public float speed;
}

public class PlatformKey : Key<PlatformData> { }

```

Now our PlatformKey looks much better.

<figure><img src="https://2203000093-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FGOxTM7Aj9oiVaIINrEkE%2Fuploads%2FRBdm73Ae9sxc5qE1IWt5%2FImage.png?alt=media&amp;token=e0a2d720-57d5-4b97-bd07-f0d13a383e4e" alt="" width="544"><figcaption><p>PlatformKey powered by Apex</p></figcaption></figure>
