AI Tree
  • 🏡Home
  • ⭐Getting Started
  • Basic
    • Behaviour Tree
      • Node
      • Decorator
      • Service
    • Blackboard
      • Key (Variable)
    • Perception System
    • Environment Query System
    • Quick Start
    • User Guide
    • Shortcuts
  • Navigation
    • Building a NavMesh
  • Nodes
    • Composite
      • Sequencer
      • Selector
        • Selector
        • Random Selector
      • Parallel
        • Parallel
        • Parallel Selector
        • Parallel Complete
    • Tasks
      • Animator
        • Cross Fade
        • Cross Fade in Fixed time
        • Set Bool
        • Set Float
        • Set Integer
        • Set Trigger
      • Audio
        • Audio Mute
        • Audio Pause
        • Audio Play
        • Audio Stop
        • Play Random Sound
        • Play Sound
        • Set Audio Clip
        • Set Audio Loop
        • Set Audio Pitch
        • Set Audio Volume
      • Audio Source
        • Play Clip At Point
      • Debug
        • Debug Log
        • Debug Draw Line
        • Debug Draw Ray
      • Common
        • Wait
        • Set Key
        • Run Behaviour
        • Wait Blackboard Time
        • Finish With Result
      • EQS
        • Run EQS Query
      • Game Object
        • Activate
        • Add Component
        • Create Object
        • Destroy Component
        • Destroy Object
        • Destroy Self
        • Detach Children
        • Find
        • Find Child
        • Find Closest
        • Get Child
        • Get Child Count
        • Get Distance
        • Get Parent
        • Get Root
        • Get Tag
        • Get Name
        • Set Parent
        • Set Tag
      • Math
        • Bool Flip
        • Bool Operator
        • Float Abs
        • Float Clamp
        • Float Operator
        • Int Abs
        • Int Clamp
        • Int Operator
        • Random Bool
        • Random Float
        • Random Int
        • Sample Curve
        • Get ACos
        • Get ASin
        • Get Atan
        • Get Atan2
        • Get Atan2 From Vector2
        • Get Atan2 From Vector3
        • Get Cos
        • Get Sin
        • Get Tan
      • Movement
        • Move Towards
        • Way Point
      • NavMesh
        • Move To
        • Random Position
      • Object
        • Destroy
        • Instantiate
      • Perception System
        • Detection Signal
      • Physics
        • Box Cast
        • Capsule Cast
        • Line Cast
        • Ray Cast
        • Sphere Cast
      • Physics2D
        • Box Cast 2D
        • Capsule Cast 2D
        • Line Cast 2D
        • Ray Cast 2D
        • Sphere Cast 2D
      • Player Prefs
        • Delete All
        • Delete Key
        • Get Float
        • Get Int
        • Get String
        • Set Float
        • Set Int
        • Set String
      • Quaternion
        • Angle Axis
        • Euler
        • From To Rotation
        • Get Euler Angles
        • Inverse
        • Multiply
        • Multiply By Vector
      • Rigidbody
        • Add Explosion Force
        • Add Force
        • Add Force At Position
        • Add Relative Force
        • Add Relative Torque
        • Add Torque
        • Move Position
        • Move Rotation
        • Sleep
        • Wake Up
      • Rigidbody2D
        • Add Force 2D
        • Add Force At Position 2D
        • Add Relative Force 2D
        • Add Torque 2D
        • Move Position 2D
        • Move Rotation 2D
        • Sleep 2D
        • Wake Up 2D
      • Transform
        • Get Angle To Target
        • Get Position
        • Get Rotation
        • Inverse Transform Direction
        • Set Scale
        • Inverse Transform Point
        • Transform Direction
        • Transform Point
      • Vector2
        • Add
        • Add XY
        • Clamp Magnitude
        • Get Length
        • Get XY
        • Invert
        • Select Random
        • Set Value
        • Set XY
      • Vector3
        • Add
        • Add XYZ
        • Clamp Magnitude
        • Get Length
        • Get XYZ
        • Invert
        • Select Random
        • Set Value
        • Set XYZ
      • Unity
        • Debug
        • Send Message
        • Find Transfrom
    • Decorators
      • Blackboard Condition
      • Compare Blackboard Keys
      • Conditional Loop
      • Cone Check
      • Inverter
      • Is At Location
      • Loop
      • Has Path
      • Object Tag Condition
      • One Time Execution
      • Succeeder
      • Time Limit
  • Perception System
    • Quick Start
    • Useful Components
      • AI Perception Blackboard
      • AI Perception Source
    • Useful Nodes
  • Environment Query System
    • Quick Start
    • Items
    • Useful Components
      • EQS Tester
    • Useful Objects
      • Environment Query
        • Generator
          • Circle
          • Cone
          • Donut
          • Grid
        • Trace Mode
          • Layer
          • NavMesh
        • Tests
          • Distance
          • Dot
          • Has Path
          • Overlap
          • Slope
          • Trace
    • Useful Nodes
  • API
    • Overview
    • User Scripting
      • Custom Task
      • Custom Key
      • ToolbarItem attribute
    • Runtime
      • BehaviourTree
      • BehaviourRunner
      • Blackboard
      • Key
      • Key<T>
      • KeyQuery
      • KeyQuery<T>
      • KeyReceiver
      • KeyReceiver<T>
      • Task Node
      • Decorator Node
      • Condition Decorator
      • Observer Decorator
      • Service Node
      • Interval Service Node
      • NodeContentAttribute
      • AIPerceptionConfig
      • EQGenerator
      • EQTraceMode
      • EQTest
  • INTEGRATIONS
    • Adventure Creator
    • A* Pathfinding Project Pro
      • Move To
    • Dialogue System for Unity
      • Lua Condition Decorator
      • Lua Run
      • Dialogue Behaviour Handler
      • Blackboard Saver
      • Lua Functions
    • Mirror Network
      • Quick Start
      • Network Instantiate
      • Network Destroy
      • Network Play Clip At Point
      • Network Debug
    • Photon Network
      • Quick Start
      • Network Instantiate
      • Network Destroy
      • Network Play Clip At Point
      • Network Debug
    • PlayMaker
      • Set Runner Active
      • Set Perception Active
      • Get Blackboard Key
      • Set Blackboard Key
    • Sensor Toolkit 2
      • Sensor Config
    • Ultimate Horror FPS KIT
      • Quick Start
      • Apply Damage
      • Animator Event Disabler
    • Odin Inspector
Powered by GitBook
On this page
  1. API
  2. User Scripting

Custom Task

Instruction to create custom user task

Last updated 6 months ago

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.

Let's create task to move platforms between two point.

This is a very simple example, we have specially chosen a simple example to make it easier to learn this material.

First of all you need to create new script. The easiest way is to use templates. Open context menu in Project window (right mouse click) and go to following path.

Create -> Renowned Games -> AI Tree -> Script Templates -> Task

We'll call it MovePlatformTask, after creation open it script in you scripts editor tool.

Task script template already contains all required code blocks, you just need to add task logic.

using RenownedGames.AITree;

[NodeContent("MovePlatformTask", "Tasks/Custom/MovePlatformTask")]
public class MovePlatformTask : TaskNode
{
    /// <summary>
    /// Called on behaviour tree is awake.
    /// </summary>
    protected override void OnInitialize()
    {
        base.OnInitialize();
    }

    /// <summary>
    /// Called when behaviour tree enter in node.
    /// </summary>
    protected override void OnEntry()
    {
        base.OnEntry();
    }

    /// <summary>
    /// Called every tick during node execution.
    /// </summary>
    /// <returns>State.</returns>
    protected override State OnUpdate()
    {
        return State.Success;
    }

    /// <summary>
    /// Called when behaviour tree exit from node.
    /// </summary>
    protected override void OnExit()
    {
        base.OnExit();
    }
}

We want to create following logic: A task is considered successful if the platform reaches one of the points after which it go to another task.

We will remove methods that are not necessary for this task so as not to overload the code.

using RenownedGames.AITree;

[NodeContent("MovePlatformTask", "Tasks/Custom/MovePlatformTask")]
public class MovePlatformTask : TaskNode
{
    /// <summary>
    /// Called on behaviour tree is awake.
    /// </summary>
    protected override void OnInitialize()
    {
        base.OnInitialize();
    }
    
    /// <summary>
    /// Called when behaviour tree enter in node.
    /// </summary>
    protected override void OnEntry()
    {
        base.OnEntry();
    }

    /// <summary>
    /// Called every tick during node execution.
    /// </summary>
    /// <returns>State.</returns>
    protected override State OnUpdate()
    {
        return State.Success;
    }
}

Let's focus on each line to understand what they are for.

// Namespace to load all required AITree API. 
using RenownedGames.AITree;
// An attribute so that the tree can see this task.
// First param: Initialname of task.
// Second param: Path to task in search context menu of the tree.
[NodeContent("Move Platform", "Tasks/Custom/Move Platform")]

The label in node content attribute may differ from the name of the class, for example, you can add spaces, symbols, numbers, etc. there.

We renamed the automatically generated MovePlatformTask label to Move Platform, just for nice display in tree graph.

// TaskNode base class for all tasks, all the tasks must be implemented from TaskNode
public class MovePlatformTask : TaskNode
// Virtual method which called on behaviour tree is awake.
protected override void OnInitialize()
// Virtual method called when behaviour tree enter in node.
protected override void OnEntry()
// Virual method which called every tick during node execution.
protected override State OnUpdate()

These are not the only virtual methods available for overloading. Each method is overloaded in a similar way and has a detailed description.


For moving platform we will use Unity transform component. Every gameobject in the scene has this component, so let's store it to easy access in every tick update.

using RenownedGames.AITree;
using UnityEngine;

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

    protected override void OnInitialize()
    {
        base.OnInitialize();
        
        // GetOwner() it's a reference to current AI entity in the scene.
        transform = GetOwner().transform;
    }
    
    protected override void OnEntry()
    {
        base.OnEntry();
    }

    protected override State OnUpdate()
    {
        return State.Success;
    }
}

Note that we used the OnInitialize() method to retrieve the Transform component, rather than OnEntry(). Although these methods may seem similar, in this case, it's preferable to use OnInitialize() because the Transform component remains unchanged throughout the game. There's no need to fetch it every time the node is entered through the OnEntry() method. Instead, we store the Transform reference once and use it throughout the entire lifecycle of the tree, improving efficiency.


In next step we need to define two point, speed and one vector for destination, for this time let's make them fixed.

using RenownedGames.AITree;
using UnityEngine;

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

    private Vector3 pointA;
    private Vector3 pointB;
    private Vector3 destination;
    private float speed;

    protected override void OnInitialize()
    {
        base.OnInitialize();
        transform = GetOwner().transform;
    
        pointA = Vector3.zero;
        pointB = new Vector3(3, 0, 0);
        destination = pointB;
        speed = 0.5f;
    }

    protected override void OnEntry()
    {
        base.OnEntry();
        if(Vector3.Distance(transform.position, pointA) < 0.1f)
        {
            destination = pointB;
        }
        else
        {
            destination = pointA;
        }
    }

    protected override State OnUpdate()
    {
        return State.Success;
    }
}

Here we implemented OnEntry() to determine the next destination point for moving before each node running. Because trasform position will change and we need to swap destination point every time before running.


Now let's implement the logic of moving between points.

using RenownedGames.AITree;
using UnityEngine;

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

    private Vector3 pointA;
    private Vector3 pointB;
    private Vector3 destination;
    private float speed;

    protected override void OnInitialize()
    {
        base.OnInitialize();
        transform = GetOwner().transform;

        pointA = Vector3.zero;
        pointB = new Vector3(3, 0, 0);
        destination = pointB;
        speed = 0.5f;
    }

    protected override void OnEntry()
    {
        base.OnEntry();
        if(destination == pointA)
        {
            destination = pointB;
        }
        else
        {
            destination = pointA;
        }
    }

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

Note that we return two different states Success and Running depending on the condition.

Success means that the node has successfully completed its task. This is the final state that tells the system that this operation has been completed successfully and need to proceed to the next node.

Running means that the node is in the process of completing its task. This status indicates that the action is ongoing and has not yet been completed. The node that returns Running will continue execution the next time the Behavior Tree is updated.

Until the platform reaches its destination, we tell the tree to update the position. After reaching the destination, we tell the tree that the next node can be started.


Done. Now we can add our task on behaviour tree window and setup simple tree.

What happed in this tree:

  1. Sequencer running task from left to right (built-in node).

  2. Move Platform task moving self to destination point.

  3. Wait task waiting for a 1 second (built-in node).

  4. Repeat.

First, we move the platform to point B (since it’s already at point A), then wait for one second. On the next entry to the MovePlatform task, we change the destination to point A (since the platform is now at point B) and repeat this process infinitely.


Result

In this example, we have described only those methods that are needed for this task, you can learn more about all the methods in this .

In this example, we have described only those states that are needed for this task, you can learn more about all the states in this .

page
page
Menu item path to Task template
MovePlatformTask script
Tree sample