x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Creating a EQS Test

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)

EQS_TeamTest.h

 UCLASS()
 class UEQS_TeamTest : public UEnvQueryTest
 {
     GENERATED_BODY()
 
     UPROPERTY(EditDefaultsOnly, Category = Team)
     int16 Team;
 
     virtual void RunTest(FEnvQueryInstance& QueryInstance) const override;
 
     virtual FString GetDescriptionTitle() const override;
     virtual FText GetDescriptionDetails() const override;    
     
 };

EQS_TeamTest.cpp

 void UEQS_TeamTest::RunTest(FEnvQueryInstance& QueryInstance) const
 {
     float MinThresholdValue = 0.0f;
     if (!QueryInstance.GetParamValue(FloatFilterMin, MinThresholdValue, TEXT("FloatFilterMin")))
     {
         return;
     }
 
     float MaxThresholdValue = 0.0f;
     if (!QueryInstance.GetParamValue(FloatFilterMax, MaxThresholdValue, TEXT("FloatFilterMax")))
     {
         return;
     }
 
     for (FEnvQueryInstance::ItemIterator It(this, QueryInstance); It; ++It)
     {    
         if ( Cast<AShadowHeroes_Unit>(QueryInstance.GetItemAsActor)->Team == Team)
         {
             It.SetScore(TestPurpose, FilterType, 1, MinThresholdValue, MaxThresholdValue);
         }
     }
     
 }
Product Version: Not Selected
Tags:
more ▼

asked Dec 08 '14 at 09:12 PM in C++ Programming

avatar image

Justin.Dooley
2.1k 104 73 163

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

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 :)

Cheers,

--mieszko

more ▼

answered Dec 08 '14 at 09:16 PM

avatar image

MieszkoZ STAFF
7.3k 225 57 413

avatar image Justin.Dooley Dec 08 '14 at 09:49 PM

After going over the code over and over again, I don't know how I missed that. Sometimes It's the little things right? ;)

avatar image MieszkoZ STAFF Dec 08 '14 at 09:58 PM

Happens to everyone :)

avatar image Justin.Dooley Dec 09 '14 at 01:51 AM

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 )

alt text

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.

output.png (4.3 kB)
avatar image Justin.Dooley Dec 09 '14 at 08:25 PM

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++;
     }
avatar image MieszkoZ STAFF Dec 17 '14 at 11:31 AM

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! :D

avatar image Justin.Dooley Dec 17 '14 at 02:31 PM

ahh that makes sense an no problem. Just let me know and I'll screw up all day for you :p

avatar image MieszkoZ STAFF Dec 17 '14 at 02:32 PM

No worries, the fix is already in the master branch :)

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question