C++ Syntax for GameplayTag Queries

Hi everyone.

I’m trying to understand how I’m supposed to use Gameplay Tag Expressions in C++.
I’m trying to write something simple: get all actors of type actor that use TagX and do NOT use TagY.

In Blueprint, I’ve reached a satisfying result, but I’m struggling to understand how to translate it in C++

I am able to do a basic query in C++ (find actors that use a certain tag), but I have no idea how Expressions are to be written and I’m having a hard time understanding UE’s source code.

This is what I have:

FGameplayTagQueryExpression spawnRoomsConditions;

// I should add the tags to the expression here

FGameplayTagQuery querySpawnRooms = GameplayTagQuery::BuildQuery(spawnRoomsConditions);
	UBlueprintGameplayTagLibrary::GetAllActorsOfClassMatchingTagQuery(GetWorld(),ARoomBox::StaticClass(),querySpawnRooms,SpawnRooms);
	for(AActor* a : SpawnRooms)
	{
		UE_LOG(LogTemp, Display, TEXT("Room Manager: retrieved actor %s"), *(a->GetName()));
	}

EDIT:

I made some progress but I’m not there yet

FGameplayTagQueryExpression spawnRoomsConditions;
	// Find rooms that allow spawn...
	spawnRoomsConditions.AddExpr(FGameplayTagQueryExpression().AllTagsMatch().AddTag(TAG_RoomAISpawn));
	// ... Except for locked rooms
	spawnRoomsConditions.AddExpr(FGameplayTagQueryExpression().NoTagsMatch().AddTag(TAG_RoomLocked));
	spawnRoomsConditions.AllExprMatch();
	for(FGameplayTagQueryExpression& expr : spawnRoomsConditions.ExprSet)
	{
		UE_LOG(LogTemp, Display, TEXT("Search type: %d"), expr.ExprType);
		for(FGameplayTag& tag: expr.TagSet)
		{
			UE_LOG(LogTemp, Display, TEXT("Search tag: %s"), *(tag.ToString()));
		}
	}
	// spawnRoomsConditions.AllTagsMatch().AddTags(TAG_RoomAISpawn)
	FGameplayTagQuery querySpawnRooms = FGameplayTagQuery::BuildQuery(spawnRoomsConditions);
	UBlueprintGameplayTagLibrary::GetAllActorsOfClassMatchingTagQuery(GetWorld(),ARoomBox::StaticClass(),querySpawnRooms,SpawnRooms);
	for(AActor* a : SpawnRooms)
	{
		UE_LOG(LogTemp, Display, TEXT("Room Manager: retrieved room %s"), *(Cast<ARoomBox>(a)->GetRoomName()));
	}

However only the first expression is added, the second one isn’t. This is the log in the editor

image

Gonna make a reply here with the final solution I got which seems to be working, in case someone else needs it in the future.

void ARoomManager::RetrieveSpawnRooms()
{
	FGameplayTagQueryExpression completeQueryExpr;
// Set the type of query (in my case, all expressions in the query need to match)

	completeQueryExpr.AllExprMatch();

// Set the first expression, by creating a new TagQueryExpression, then setting it to the required type (in my case, the first expression needs to have all tags matching)
 completeQueryExpr.AddExpr(FGameplayTagQueryExpression().AllTagsMatch().AddTag(TAG_RoomAISpawn));

// Set the second expression, by creating a new TagQueryExpression, then setting it to the required type (in my case, the second expression needs to have all tags NOT matching)

completeQueryExpr.AddExpr(FGameplayTagQueryExpression().NoTagsMatch().AddTag(TAG_RoomLocked));
// "Debug" logs

// Cycle through each child expression contained in the final one
	for(FGameplayTagQueryExpression& expr : completeQueryExpr.ExprSet)
	{
// Print the ExpressionType (this indicates if it's an "all tags match", "any tags match" etc
		UE_LOG(LogTemp, Display, TEXT("Search type: %d"), expr.ExprType);
// Cycle through each tag inside the expression and print it
		for(FGameplayTag& tag: expr.TagSet)
		{
			UE_LOG(LogTemp, Display, TEXT("Search tag: %s"), *(tag.ToString()));
		}
	}
	FGameplayTagQuery GameplayTagQuery= FGameplayTagQuery::BuildQuery(completeQueryExpr);

// Finally, let's log the result 
UBlueprintGameplayTagLibrary::GetAllActorsOfClassMatchingTagQuery(GetWorld(),ARoomBox::StaticClass(),GameplayTagQuery,anArrayOfActors);
	for(AActor* a : anArrayOfActors)
	{
		UE_LOG(LogTemp, Display, TEXT("Found %s"), *(a->GetName()));
	}
}