# Custom 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="/files/o8MOrCaGDBsH5T1huidH" 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="/files/cqFEQjQLCYF0ZXsQY24F" 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="/files/5IXeMWqvFtmohvJpBWAU" alt="" width="544"><figcaption><p>PlatformKey powered by Apex</p></figcaption></figure>


---

# 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://renownedgames.gitbook.io/ai-tree/api/user-scripting/custom-key.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.
