I’m trying to create a EQS test that is used with the Actors of type generator. the purpose of the test is to check the team variable inside the class passed. ( I understand that it’s not very generic but it will get the job done for now ). I’m just taking a shot at it by looking at the EQS Distance Test but I’m having trouble converting the QueryInstance to my specific actor class. I imagine that this is because tests are supposed to be able to be used with any kind of generator but I just don’t have a switch in there yet. This is where I stand so far but the Cast< AShadowHeroes_Unit >(QueryInstance.GetItemAsActor) throws an error.
If anyone can help point me in the correct direction, I’d appreciate it.
I know it should be more generic than it is, but It’s a proof of concept before I try to include a templated class parameter to the test. (I’ll look at how it’s done in the actors of class generator)
What kind of error does it throw at you? If you just copy-pasted your code here I’d guess the problem is that you’re missing parenthesis in your GetItemAsActor call
This is a bit odd, it looks like the iterator is not moving across the actors. Inside my Run Test I have this:
int i = 0;
for (FEnvQueryInstance::ItemIterator It(this, QueryInstance); It; ++It)
{
i++;
UE_LOG(LogTemp, Warning, TEXT("%s T-%d : Test - %d"),
*(Cast<AShadowHeroes_Unit>(QueryInstance.GetItemAsActor(It)))->GetName(),
Cast<AShadowHeroes_Unit>(QueryInstance.GetItemAsActor(It))->Team,
Team);
if ( (Cast<AShadowHeroes_Unit>(QueryInstance.GetItemAsActor(It)))->Team == Team )
{
UE_LOG(LogTemp, Warning, TEXT("%d : Pass"), i);
It.SetScore(TestPurpose, EEnvTestFilterType::Match, 1, 1);
}
else
{
UE_LOG(LogTemp, Warning, TEXT("%d : Fail"), i);
It.SetScore(TestPurpose, EEnvTestFilterType::Match, 0, 1);
}
}
Yet my output is always the same for the actor being checked. The name of the actor should be changing as it move across the actors in range. ( I do a distance check as well which I assume is running first since both tests are low and distance is listed first )
What is the relationship between the Item Iterator and the test? I thought the iterator would go over each item being tested and by calling QueryInstance.GetItemAsActor(It) it would return the actor related to that test. but it seems that it only return the first instance.
Ok I got it to iterate though it was not very intuitive. It actually feels kind of dirty to be using a int value inside a iterator for loop. It feels kind of hacky right now. Is this the intended way of getting actors?
int i = 0;
for (FEnvQueryInstance::ItemIterator It(this, QueryInstance); It; ++It)
{
if ((Cast<AShadowHeroes_Unit>(QueryInstance.GetItemAsActor(QueryInstance.ItemDetails[i].ItemIndex)))->Team == Team)
{
It.SetScore(TestPurpose, EEnvTestFilterType::Match, 1, 1);
}
else
{
It.SetScore(TestPurpose, EEnvTestFilterType::Match, 0, 1);
}
i++;
}
I finally had a moment to look at this, and there’s a bug in your code: QueryInstance.GetItemAsActor(It) will always result in getting the actor at index 1 since using pure It in this case will result in converting it to bool rather then int32 index. Use *It instead.
I’ve noticed one of engine level tests recently added ( UEnvQueryTest_GameplayTags ) suffers from the same issue. I’ll get it fixed right away.
Also, I’ll add a kind of safety feature so this gets detected in the future. Thanks for making this mistake that will result in more robust EQS code!