Skip to content

[GAS] Native gameplay tags

Gameplay tag macros

#include "GameplayTagContainer.h"
#include "GameplayTagsManager.h"

#define TagNodeRoot(Name) struct Name : NVInternalTagTree { using NVInternalTagTree::NVInternalTagTree;
#define TagNodeRoot_() };

#define TagNode(Name) struct : NVInternalTagTree { using NVInternalTagTree::NVInternalTagTree;
#define TagNode_(Name) } Name{ #Name, this };

#define Tag(Name) NVInternalTag Name{ #Name, this };
#define TagAndCue(Name) NVInternalTag Name{ #Name, this }; NVInternalTag Name##Cue{ #Name, this, true };

#define EffectTag(Name) NVInternalTag Name{ #Name, this};

extern TMap<FGameplayTag*, FName> StrTags;

struct NVInternalTagTree
{
    friend struct NVInternalTag;

    explicit NVInternalTagTree() : Parent{nullptr}
    {}

    NVInternalTagTree(UGameplayTagsManager& InManager, const FString& Name, NVInternalTagTree* parent) : Parent{parent},
        Path{ parent->Path.IsEmpty() ? Name : parent->Path + "." + Name }
    {
        StrTags.Add(&Tag, FName(Path));
    }

    NVInternalTagTree(FString Name, NVInternalTagTree* InParent) : Parent{InParent}, Path{InParent->Path.IsEmpty() ? Name : InParent->Path + "." + Name}
    {}

    operator FGameplayTag() const { return Tag; }

private:
    NVInternalTagTree* Parent;
    FString Path;
    FGameplayTag Tag;
};

struct NVInternalTag
{
    NVInternalTag(const FString& Name, const NVInternalTagTree* const TagTree)
    {
        if (!TagTree->Path.IsEmpty()) StrTags.Add(&Tag, FName(TagTree->Path + "." + Name));
        else StrTags.Add(&Tag, FName(Name));
    }

    NVInternalTag(const FString& Name, const NVInternalTagTree* const TagTree, bool)
    {
        if (!TagTree->Path.IsEmpty()) StrTags.Add(&Tag, FName("GameplayCue." + TagTree->Path + "." + Name));
        else StrTags.Add(&Tag, FName("GameplayCue." + Name));
    }

    operator FGameplayTag() const { return Tag; }

private:
    FGameplayTag Tag;
};

Gameplay tag initialization

Initialize in the project module

IMPLEMENT_PRIMARY_GAME_MODULE(FNVModule, nverse, "nverse");

TMap<FGameplayTag*, FName> StrTags;

GasTags NVTag;
StatTags NVStatRoot;

void FNVModule::StartupModule()
{
    auto& Manager = UGameplayTagsManager::Get();

    for (auto& [TagPtr, TagName] : StrTags)
    {
        *TagPtr = Manager.AddNativeGameplayTag(TagName);
    }

    UGameplayTagsManager::Get().DoneAddingNativeTags();
}