Add Has Tag decorator
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Core/Types/Variant.h"
|
||||
#include "Engine/Core/Types/VariantValueCast.h"
|
||||
#include "Engine/Serialization/SerializationFwd.h"
|
||||
|
||||
class BehaviorKnowledge;
|
||||
@@ -70,7 +71,7 @@ API_STRUCT(InBuild, Template, MarshalAs=StringAnsi) struct FLAXENGINE_API Behavi
|
||||
// Gets the selected knowledge value (typed).
|
||||
FORCE_INLINE T Get(BehaviorKnowledge* knowledge)
|
||||
{
|
||||
return (T)BehaviorKnowledgeSelectorAny::Get(knowledge);
|
||||
return TVariantValueCast<T>::Cast(BehaviorKnowledgeSelectorAny::Get(knowledge));
|
||||
}
|
||||
|
||||
// Tries to get the selected knowledge value (typed). Returns true if got value, otherwise false.
|
||||
@@ -79,7 +80,7 @@ API_STRUCT(InBuild, Template, MarshalAs=StringAnsi) struct FLAXENGINE_API Behavi
|
||||
Variant variant;
|
||||
if (BehaviorKnowledgeSelectorAny::TryGet(knowledge, variant))
|
||||
{
|
||||
value = (T)variant;
|
||||
value = TVariantValueCast<T>::Cast(variant);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#if USE_CSHARP
|
||||
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
||||
#endif
|
||||
#include "Engine/Level/Actor.h"
|
||||
#include "Engine/Serialization/Serialization.h"
|
||||
|
||||
bool IsAssignableFrom(const StringAnsiView& to, const StringAnsiView& from)
|
||||
@@ -445,3 +446,13 @@ bool BehaviorTreeKnowledgeValuesConditionalDecorator::CanUpdate(const BehaviorUp
|
||||
{
|
||||
return BehaviorKnowledge::CompareValues((float)ValueA.Get(context.Knowledge), (float)ValueB.Get(context.Knowledge), Comparison);
|
||||
}
|
||||
|
||||
bool BehaviorTreeHasTagDecorator::CanUpdate(const BehaviorUpdateContext& context)
|
||||
{
|
||||
bool result = false;
|
||||
::Actor* actor;
|
||||
if (Actor.TryGet(context.Knowledge, actor) && actor)
|
||||
result = actor->HasTag(Tag);
|
||||
result ^= Invert;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
#include "Engine/Core/Collections/Array.h"
|
||||
#include "Engine/Core/Collections/BitArray.h"
|
||||
#include "Engine/Content/AssetReference.h"
|
||||
#include "Engine/Level/Tags.h"
|
||||
|
||||
class Actor;
|
||||
|
||||
/// <summary>
|
||||
/// Base class for compound Behavior Tree nodes that composite child nodes.
|
||||
@@ -342,3 +345,28 @@ public:
|
||||
// [BehaviorTreeNode]
|
||||
bool CanUpdate(const BehaviorUpdateContext& context) override;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Checks if certain actor (from knowledge) has a given tag assigned.
|
||||
/// </summary>
|
||||
API_CLASS(Sealed) class FLAXENGINE_API BehaviorTreeHasTagDecorator : public BehaviorTreeDecorator
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_WITH_CONSTRUCTOR_IMPL(BehaviorTreeHasTagDecorator, BehaviorTreeDecorator);
|
||||
API_AUTO_SERIALIZATION();
|
||||
|
||||
// The actor value from behavior's knowledge (blackboard, goal or sensor) to check against tag ownership.
|
||||
API_FIELD(Attributes="EditorOrder(0)")
|
||||
BehaviorKnowledgeSelector<Actor*> Actor;
|
||||
|
||||
// The tag to check.
|
||||
API_FIELD(Attributes="EditorOrder(10)")
|
||||
Tag Tag;
|
||||
|
||||
// If checked, inverts condition - checks if actor doesn't have a tag.
|
||||
API_FIELD(Attributes="EditorOrder(20)")
|
||||
bool Invert = false;
|
||||
|
||||
public:
|
||||
// [BehaviorTreeNode]
|
||||
bool CanUpdate(const BehaviorUpdateContext& context) override;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Core/Types/Variant.h"
|
||||
#include "Engine/Core/Templates.h"
|
||||
|
||||
// Helper utility to read Variant value with automatic casting to the template type (eg. cast ScriptingObject* to Actor*).
|
||||
template<typename T, typename Enable = void>
|
||||
struct TVariantValueCast
|
||||
{
|
||||
FORCE_INLINE static T Cast(const Variant& v)
|
||||
{
|
||||
return (T)v;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct TVariantValueCast<T*, typename TEnableIf<TIsBaseOf<class ScriptingObject, T>::Value>::Type>
|
||||
{
|
||||
FORCE_INLINE static T* Cast(const Variant& v)
|
||||
{
|
||||
return ScriptingObject::Cast<T>((ScriptingObject*)v);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user