diff --git a/Source/Engine/AI/BehaviorTreeNodes.cpp b/Source/Engine/AI/BehaviorTreeNodes.cpp index 57149aa04..fa40dd8e1 100644 --- a/Source/Engine/AI/BehaviorTreeNodes.cpp +++ b/Source/Engine/AI/BehaviorTreeNodes.cpp @@ -99,6 +99,40 @@ BehaviorUpdateResult BehaviorTreeSequenceNode::Update(BehaviorUpdateContext cont return result; } +int32 BehaviorTreeSelectorNode::GetStateSize() const +{ + return sizeof(State); +} + +void BehaviorTreeSelectorNode::InitState(Behavior* behavior, void* memory) +{ + auto state = GetState(memory); + new(state)State(); +} + +BehaviorUpdateResult BehaviorTreeSelectorNode::Update(BehaviorUpdateContext context) +{ + auto state = GetState(context.Memory); + + if (state->CurrentChildIndex >= Children.Count()) + return BehaviorUpdateResult::Failed; + + auto result = Children[state->CurrentChildIndex]->InvokeUpdate(context); + + switch (result) + { + case BehaviorUpdateResult::Success: + return BehaviorUpdateResult::Success; + case BehaviorUpdateResult::Failed: + state->CurrentChildIndex++; // Move to the next node + if (state->CurrentChildIndex < Children.Count()) + result = BehaviorUpdateResult::Running; // Keep on running to the next child on the next update + break; + } + + return result; +} + int32 BehaviorTreeDelayNode::GetStateSize() const { return sizeof(State); diff --git a/Source/Engine/AI/BehaviorTreeNodes.h b/Source/Engine/AI/BehaviorTreeNodes.h index d8e447029..9d6683d74 100644 --- a/Source/Engine/AI/BehaviorTreeNodes.h +++ b/Source/Engine/AI/BehaviorTreeNodes.h @@ -45,6 +45,26 @@ private: }; }; +/// +/// Selector node updates all its children (from left to right) until one of them succeeds. If all children fail, the selector fails. +/// +API_CLASS() class FLAXENGINE_API BehaviorTreeSelectorNode : public BehaviorTreeCompoundNode +{ + DECLARE_SCRIPTING_TYPE_WITH_CONSTRUCTOR_IMPL(BehaviorTreeSelectorNode, BehaviorTreeCompoundNode); + +public: + // [BehaviorTreeNode] + int32 GetStateSize() const override; + void InitState(Behavior* behavior, void* memory) override; + BehaviorUpdateResult Update(BehaviorUpdateContext context) override; + +private: + struct State + { + int32 CurrentChildIndex = 0; + }; +}; + /// /// Root node of the behavior tree. Contains logic properties and definitions for the runtime. ///