diff --git a/Source/Engine/AI/BehaviorTreeNodes.cpp b/Source/Engine/AI/BehaviorTreeNodes.cpp index 783ac9157..57149aa04 100644 --- a/Source/Engine/AI/BehaviorTreeNodes.cpp +++ b/Source/Engine/AI/BehaviorTreeNodes.cpp @@ -1,7 +1,9 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #include "BehaviorTreeNodes.h" +#include "Behavior.h" #include "BehaviorKnowledge.h" +#include "Engine/Core/Random.h" #include "Engine/Serialization/Serialization.h" BehaviorUpdateResult BehaviorTreeNode::InvokeUpdate(const BehaviorUpdateContext& context) @@ -96,3 +98,23 @@ BehaviorUpdateResult BehaviorTreeSequenceNode::Update(BehaviorUpdateContext cont return result; } + +int32 BehaviorTreeDelayNode::GetStateSize() const +{ + return sizeof(State); +} + +void BehaviorTreeDelayNode::InitState(Behavior* behavior, void* memory) +{ + auto state = GetState(memory); + if (!WaitTimeSelector.TryGet(behavior->GetKnowledge(), state->TimeLeft)) + state->TimeLeft = WaitTime; + state->TimeLeft = Random::RandRange(Math::Max(WaitTime - RandomDeviation, 0.0f), WaitTime + RandomDeviation); +} + +BehaviorUpdateResult BehaviorTreeDelayNode::Update(BehaviorUpdateContext context) +{ + auto state = GetState(context.Memory); + state->TimeLeft -= context.DeltaTime; + return state->TimeLeft <= 0.0f ? BehaviorUpdateResult::Success : BehaviorUpdateResult::Running; +} diff --git a/Source/Engine/AI/BehaviorTreeNodes.h b/Source/Engine/AI/BehaviorTreeNodes.h index 67d19099a..d8e447029 100644 --- a/Source/Engine/AI/BehaviorTreeNodes.h +++ b/Source/Engine/AI/BehaviorTreeNodes.h @@ -2,7 +2,9 @@ #pragma once +#include "BehaviorKnowledge.h" #include "BehaviorTreeNode.h" +#include "BehaviorKnowledgeSelector.h" #include "Engine/Core/Collections/Array.h" /// @@ -59,3 +61,36 @@ API_CLASS(Sealed) class FLAXENGINE_API BehaviorTreeRootNode : public BehaviorTre API_FIELD(Attributes="EditorOrder(10)") float UpdateFPS = 10.0f; }; + +/// +/// Delay node that waits a specific amount of time while executed. +/// +API_CLASS(Sealed) class FLAXENGINE_API BehaviorTreeDelayNode : public BehaviorTreeNode +{ + DECLARE_SCRIPTING_TYPE_WITH_CONSTRUCTOR_IMPL(BehaviorTreeDelayNode, BehaviorTreeNode); + API_AUTO_SERIALIZATION(); + + // Time in seconds to wait when node gets activated. Unused if WaitTimeSelector is used. + API_FIELD(Attributes="EditorOrder(10), Limit(0)") + float WaitTime = 3.0f; + + // Wait time randomization range to deviate original value. + API_FIELD(Attributes="EditorOrder(20), Limit(0)") + float RandomDeviation = 0.0f; + + // Wait time from behavior's knowledge (blackboard, goal or sensor). If set, overrides WaitTime but still uses RandomDeviation. + API_FIELD(Attributes="EditorOrder(30)") + BehaviorKnowledgeSelector WaitTimeSelector; + +public: + // [BehaviorTreeNode] + int32 GetStateSize() const override; + void InitState(Behavior* behavior, void* memory) override; + BehaviorUpdateResult Update(BehaviorUpdateContext context) override; + +private: + struct State + { + float TimeLeft; + }; +};