Add Has Tag decorator

This commit is contained in:
2023-08-25 10:42:53 +02:00
parent b31f262214
commit 99547a1ff4
4 changed files with 67 additions and 2 deletions
+3 -2
View File
@@ -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;
+11
View File
@@ -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;
}
+28
View File
@@ -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);
}
};