GithubHelp home page GithubHelp logo

sinyavtsevilya / dots-behaviortree Goto Github PK

View Code? Open in Web Editor NEW
57.0 2.0 11.0 36 KB

Unity DOTS Behavior-Tree implementation

License: MIT License

C# 100.00%
dots ecs unity behavior-trees behavior-tree-editor burst

dots-behaviortree's Introduction

DOTS-BT

Unity DOTS Behavior-Tree implementation

title

Features

  • High performance. Zero GC allocations.
  • Easy to use, less to code.
  • 100% ECS-ish. No blackboards, no unrelated systems to think about.
  • Supports all classic composite node types: Selector, Sequence, Repeater.
  • Conditional aborts support.
  • Creating (and editing) a tree in Unity Editor.
  • Compatible with burst and il2cpp.

HowTo

Requirements

Min. Requirements: Unity >= 2019.4.18 and entities package >= 0.11.2-preview.1

Tested on: Unity 2020.2.3 and entities package 0.17.0-preview.42

Installation

You can install the repository using UPM: Just add this line in Packages/manifest.json:

"com.nanory.unity.entities.bt": "https://https://github.com/SinyavtsevIlya/DOTS-BehaviorTree.git",

Usage

1) Create a new behavior tree

By right-clicking the Hierarchy > Behavior Tree > Root

2) Create any nested nodes you need

(Selector/Sequence/Repeater) doing the same way as shown in first step. nodes-creation

3) Create your own action or conditional node.

To make it you need to create a pair: a component and a system.

Action Node example:

// 1) Create an action node component and (optional) add this attribute.
[GenerateAuthoringComponent]
public struct SeekEnemy : IComponentData { }

public sealed class BTSeekEnemySystem : SystemBase
{
   protected override void OnUpdate()
   {
       var beginSimECB = this.CreateBeginSimECB();
       
       Entities
           .WithAll<SeekEnemy>() // 2) Simply add it to your Query.
           .ForEach((Entity agentEntity, 
           // The parameters below are just up to you. 
           in EnemyLink enemyLink, 
           in LocalToWorld ltw,
           in StoppingDistance stoppingDistance, 
           in BTActionNodeLink bTNodeLink) => // 3) But don't forget to add this component in the end.
           {
               var position = GetComponent<LocalToWorld>(enemyLink.Value).Position;

               if (math.length((position - ltw.Position)) < stoppingDistance.Value)
               {
                   // 4) When you decided that the action was completed successfully, then you need to send the result.
                   beginSimECB.AddComponent(bTNodeLink.Value, BTResult.Success); 
               }
               else
                   beginSimECB.AddComponent(agentEntity, new MoveToDestinationRequest() { Position = position, Speed = 1f });
           })
           .ScheduleParallel();
   }
}

Conditional Node example is very similar except two things:

// 1) NOTE: in this case we need to implement interface IConditional. (It's only for conversion/validation purposes, not for runtime)
[GenerateAuthoringComponent]
public struct BTIsEnemyReachable : IComponentData, IConditional{ }

public sealed class BTIsEnemyReachableSystem : SystemBase
{
    protected override void OnUpdate()
    {
        var beginSimECB = this.CreateBeginSimECB();

        Entities
            .WithAll<BTIsEnemyReachable>()
            .ForEach(
            (DynamicBuffer<InteractableElement> interactableElements, 
            in EnemyLink enemyLink,
            in Name name,
            // 2) NOTE: we need to pass a Conditional Node reference.
            in BTConditionalNodeLink bTNodeLink) =>
            {
                for (int i = 0; i < interactableElements.Length; i++)
                {
                    if (interactableElements[i].value == enemyLink.Value)
                    {
                        beginSimECB.AddComponent(bTNodeLink.Value, BTResult.Success);
                        return;
                    }
                }
                // you also able to send "Fail" results.
                beginSimECB.AddComponent(bTNodeLink.Value, BTResult.Fail);
            })
            .WithoutBurst()
            .Run();
    }
}

4) Add your newly created nodes in the tree

// TODO

5) Connect tree to agent

// TODO

Advanced Tips

How to use conditional aborts

// TODO (basic usage, priorities)

How to react on state changes

// TODO (enter/exit events)

FAQ

Is it posible to use nested trees?

Yes. Since the tree is just a prefab it's easy to make using nested prefabs feature.

dots-behaviortree's People

Contributors

sinyavtsevilya avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

dots-behaviortree's Issues

Struct restriction

Is there any specific reason that components need to be structs? Is that Lex/LeoECS purely being opinionated or am I missing something? Arrays are guaranteed to have a linear layout, even for reference types. Is this due to the indirection via the ItemPool struct?

I know that in an ideal performance-oriented world we'd just have structs filled with value fields, but having to handle references to components via ref is a pain (and potentially prone to errors, because, you know, structs generally shouldn't be passed around as refs most of the time...). So unless I'm missing something, allowing reference types as components wouldn't necessarily negatively impact performance for pools/systems that only utilize structs, right? If so, why not open up the architecture a little and drop the struct enforcing?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.