Skip to content

Simple node based Behaviour Tree implementation

License

MIT, Unknown licenses found

Licenses found

MIT
LICENSE
Unknown
LICENSE.meta
Notifications You must be signed in to change notification settings

recstazy/BehaviourTree

Repository files navigation

BehaviourTree

Simple node based Behaviour Tree implementation for AI programming in Unity Made with Graph View

This is not a fully-supported project, I'm working on it in my free time.

image


Watch the execution

  • Use top toolbar to choose a target and see what happens in runtime

  • Use "Window/Blackboard Watcher" to see or change values in the runtime blackboard instanced fot a target

Write a blackboard

using Recstazy.BehaviourTree;

[CreateAssetMenu(menuName = "Behaviour Tree/MyBlackboard")]
public class MyBlackboard : Blackboard
{
    // Use serialized fields to monitor values or assign them in editor
    [SerializeField]
    private bool _booleanValue;

    [SerializeField]
    private ScriptableObject _someScriptable;

    // Properties are what exposed to the behaviour tree editor window
    public bool BooleanValue { get => _booleanValue; set => _booleanValue = value; }

    // Complex things are supported too
    public ScriptableObject SomeScriptable { get => _someScriptable; set => _someScriptable = value; }

    // You don't technically need the serialized field
    public float FloatValue { get; set; }

    // Access modifiers also work
    public float OnlyGetFloat { get; private set; } // You won't be able to change this
    public float OnlySetFloat { private get; set; } // Or get this

    [HideInTree] // Don't expose this property to the behaviour tree window
    public float HiddenFloat { get; set; }

    // Why properties?
    // Because they work through delegates instead of FieldInfo.GetValue(obj)
    // 1200ms(field) vs 80ms(prop) for 1 million operations
}

Write your own tasks:

Write simple task with fields

using Recstazy.BehaviourTree;

[TaskOut] // This creates executable output. 
[TaskMenu("My Awesome Tasks/Hello World")]
public class HelloWorld : BehaviourTask
{
    // Fields just like you normally do
    [SerializeField]
    private string _logString = "Hello World";

    // What we do in this task
    protected override IEnumerator TaskRoutine()
    {
        Debug.Log("Hello World");
        yield return new WaitForSeconds(1f);

        // You can fail task
        // Execution will stop here if Succeed == false
        // True by default

        // Some nodes like Selector and Sequencer
        // will use this result to make decisions
        Succeed = true;
    }
}
    

Write more complex task with inputs and different outputs

using Recstazy.BehaviourTree;

[TaskMenu("Branch")]
[TaskOut("True"), TaskOut("False")] // Name your outputs
public class Branch : BehaviourTask
{
    // Input connection pin with a bool value
    [SerializeField]
    private InputValue<bool> _bool;

    protected override int GetNextOutIndex()
    {
        // Return out[0] (we named it "True") or out[1] ("False") depending on value
        // Execution will continue from this out
        return _bool.Value ? 0 : 1;
    }

    // This is not neccessary
    // default behavior is to wait one frame and Succeed
    protected override IEnumerator TaskRoutine()
    {
        yield break;
    }
}

Multiout task will generate outputs while you're connecting them. You can define concrete outputs as usual but there will be always one more pin to connect something

/// <summary>
/// Executes random connection
/// </summary>
[TaskMenu("Tasks/Run Random")]
public class RunRandom : MultioutTask
{
    protected override int GetNextOutIndex()
    {
        return Random.Range(0, Connections.Count);
    }
}

About

Simple node based Behaviour Tree implementation

Resources

License

MIT, Unknown licenses found

Licenses found

MIT
LICENSE
Unknown
LICENSE.meta

Stars

Watchers

Forks

Packages

No packages published

Languages