Blueprint - EQS and Gameplay Tags - I need help!

Hello all,

I’ve encountered a problem with EQS that I can’t solve myself and have found no other examples of it on the internet (with one exception but its outdated, I think).

Essentially I want two teams of AI characters to move, attack, flank etc using Blackboard, and EQS seems really good for that. I have set up some basic gameplay tags, for simple things (alive or dead etc) and teams, friendly (to the player) and hostile (to the player). Disclaimer I am still quite new to the AI side of things. To test, when they got within range of the player the would move towards them. Along the way an EQS test would run to see if other AI (of the opposite team) were closer (to attack first).

The crux of the problem is that when using EQS to detect actors in proximity, the gameplay tags simply don’t work for me. Looking at the generator in the debug view it marks the test as SKIP (see below) rather than give it a score or filter it. If gameplay tags are the only test it passes everything, within the class specified. So the test returns is neither true or false, based on purely on the gameplay tags and any actor in the class randomly wins by default.

A change I could make would be to split the AI into two classes based on the teams and search purely for that, but I need to include the player within the test as well, so they can be attacked too. Also I would like to avoid doing that at this point.

CurrentTags
Tag setup


Ideal test, Any or All appears to make no difference. Distance test works fine.

SkipResult
With only the gameplay tags test enabled this is a typical result.

TagPrint
Getting each character to print their tags, which are not on by default.

BothTests
This is both the tags and distance test seen above. Still has the SKIP result. (Have not found any info on this)

Having tried numerous things my questions are this.

  1. Is there something I’m missing / am I doing it wrong?
  2. Is this a bug or unintended?
  3. Does anyone else have an example they can please share with me? (I haven’t been able to find a single one.) Most tutorials cover other test types which haven’t helped yet.
  4. I have also not been able to get the ‘Get All Actors Of Class Matching Tag Query’ to work as a replacement. Maybe the reasons are connected haha?

Things I have tried already.

  • Verified the tags are present on the character being tested. I have now set it up with the default tag container is empty and based on what team is spawns for, it adds ‘friendly’ or ‘hostile’ and ‘alive’ to both. I can print these out from each actor’s gameplay tag container to verify them.
  • Tried using the EQS pawn, the test performs the same. Every actor returns a 0.00 score but is not filtered out. This means at runtime it usually defaults to the player ‘winning’.
  • Accounted for the fact the query may be looking for exact (any, all, none) or not. I can’t see a way to tell in the test. It doesn’t even look like queries even use exact tests anyway only matches in BPs.
  • Tried adding a single tag to query against, single tag to a container, multiple tags in a container. No change in results.
  • Adjusted the generator itself to see it that would make a difference, i.e. search for [actors/characters/specficAIclass] within X range. I thought that might mess it up somehow.
  • Tried every combination of EQS settings I could think of, in the generator and on the pawn. i.e. single best, all matching, scored, filtered, query matching all, any, none, bool match (t/f) etc. All other types of tests seem to work fine.
  • Adjusted the tag hierarchy to make it as simple as possible. (Would redirects be a problem?)
  • Created a new project. Setup the EQS, AI, tags etc. again simplified, no luck. (See below)


Trying alternative in BP, this also doesn’t work


What is looking for, setting the team via tags


Simple spawn event to set the team

Thats it
Tags in question, simplest setup possible


The EQS test that looks for the above tag, set in the above way.

Apologies for the long post but, what in tarnation am I missing???
Any help would be much appreciated!

Hi, GameplayTags test and GetAllActorsOfClassMatchingTagQuery works fine for me (UE 4.26). Your actors there did implement the IGameplayTagAssetInterface in C++, right?

Hello, thanks for your reply!!

Ah, no that has not been done…Might explain my troubles haha.
Going by the documentation I was working under the impression that I could use tags purely with blueprints alone :upside_down_face:
That definitely gave me something to work with, thank you!

I certainly seems like its a problem with tags, not EQS, so it seem pretty likely that’s the problem.

Ok, I have a few more questions if you will humor me.

I think I’ve found a few tutorials on how to do it, just want to make sure I’m back on the right path again.

Thanks again!

Is that the only thing that’s missing do you think?

Yes that should be the only thing missing.

How do I implement that on a BP project?

You can’t. You need to implement it in C++. So what you could do, is:

(-) let your blueprint actors inherit from C++ classes (e. g. if your blueprint inherits from “Character”, then create a new C++ class that inherits from “Character”, lets name it “MyCharacterCPP”, then let your blueprint inherit from “MyCharacterCPP”).

(-) inside “MyCharacterCPP” you implement the “IGameplayTagAssetInterface”. So your “MyCharacterCPP.h” can look like this (minimalistic example):

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "GameplayTags.h"
#include "MyCharacterCPP.generated.h"

UCLASS()
class NEWGAMEPROJECT_API AMyCharacterCPP : public ACharacter, public IGameplayTagAssetInterface
{
	GENERATED_BODY()

	// autogenerated stuff -------------------------

public:
	// Sets default values for this character's properties
	AMyCharacterCPP();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	// Called to bind functionality to input
	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

	// ---------------------------------------------


	// Need to store the GameplayTags somewhere. EditAnywhere and BlueprintReadWrite is so that you can add tags in BP.
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FGameplayTagContainer GameplayTagContainer;


	// Gameplay Tag Interface implementation

	virtual void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const override { TagContainer = GameplayTagContainer; return; }

	virtual bool HasMatchingGameplayTag(FGameplayTag TagToCheck) const override { return GameplayTagContainer.HasTag(TagToCheck); }

	virtual bool HasAllMatchingGameplayTags(const FGameplayTagContainer& TagContainer) const override { return GameplayTagContainer.HasAll(TagContainer); }

	virtual bool HasAnyMatchingGameplayTags(const FGameplayTagContainer& TagContainer) const override { return GameplayTagContainer.HasAny(TagContainer); }


};

No need to change anything in the .cpp file.

And then you need to include the “GameplayTags” Module in your project. So inside the “InsertYourProjectNameHere.Build.cs” you add “GameplayTags” to your PublicDependencyModuleNames, so mine currently looks like:

PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "NavigationSystem", "AIModule", "OnlineSubsystem", "OnlineSubsystemNull", "OnlineSubsystemUtils", "GameplayTags", "PhysicsCore", "GameplayAbilities", "GameplayTasks"});

I don’t know anymore how much of it was there by default, but you only need to add “GameplayTags” to it =)

4 Likes

Hi, sorry I wasn’t able to work on the project for a few days and get back to you.

Yes! This worked, thank you so much!

Edit for anyone else seeking answers in the future:

  • Provided you have done the above correctly it allows for gameplay tags to actually work as set out in the UE documentation. They probably should to be updated to reflect that.

  • Once you have the class inheritance (found via Class settings on the BP toolbar) linked like so, (Engine base Character class > new C++ class > your AI character) you no longer need a specific gameplay container variable, it is now there as a class default, just right click in your blueprint graph and search for it.

  • To add a C++ class to a BP project, simply go to File>New C++ class, select Character, create and also choose public, I would imagine. Use Visual Studio or something similar to edit the character file and your Project file with the above. I found the project file the hack way by searching .cs in my project folder, at the top level. It is probably in “YouProjectName/Source/YourProjectName” as a “YourProjectName.cs” file. I’m unsure if any further steps need to be done here.

  • Make sure to add or set you gameplay tags to the actors specific container so queries, like EQS, can actually look at them and return the result you are expecting.

3 Likes

Please help! Why can’t I get the node **Get All Actors Of Class Matching Tag **to work. It always returns empty array.

Your AI is probably not implementing the Gameplay Tag Interface.