4.8.1: AI Perception By Affiliation?

Hello everyone!
I have this exact same bug in 4.21.2 and, recently, Epic told me that this is not a priority, so I looked for a workaround. There are 3 options:

  1. Copy/Paste: you can copy/paste values in the invisible field. Simply copy this line with whatever flag values you want and paste it over the bugged field in the details panel (bDetectEnemies=True,bDetectNeutrals=True,bDetectFriendlies=True)

  2. Grab the component: add the component in Editor to your AI/Player Controller and then, in BeginPlay() within your actor c++ class, use UAIPerceptionComponent* MyPerceptionComponent = FindComponentByClass<UAIPerceptionComponent>();

  3. Force flags in c++:

    //Create a custom AIPerceptionComponent Class like this:
    

    //MyAIPerceptionComponent.h

    #pragma once
    #include “Perception/AIPerceptionComponent.h”
    #include “MyAIPerceptionComponent.generated.h”

    UCLASS()
    class UMyAIPerceptionComponent : public UAIPerceptionComponent
    {
    GENERATED_BODY()

    public:

    virtual void OnRegister() override;

    /** this is a hack because of bugissues.unrealengine.com/issue/UE-18378

    • if you add a custom sense that uses affiliation, add a section for it within this function

    • Call this on begin play for every actor with a PerceptionComponent added in c++

    • Call this also every time you add a new sense to said actor that uses Affiliation tags
      */
      void SetAllSensesDetectionAffiliation();
      };

      //MyAIPerceptionComponent.cpp

      #include “MyAIPerceptionComponent.h”
      #include “Perception/AISenseConfig.h”
      #include “Perception/AISenseConfig_Hearing.h”
      #include “Perception/AISenseConfig_Sight.h”

      void UMyAIPerceptionComponent::OnRegister()
      {
      SetAllSensesDetectionAffiliation();

      //called last because we need to do the hack before registering it
      Super::OnRegister();
      }

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

     void UMyAIPerceptionComponent::SetAllSensesDetectionAffiliation()
     {
        for (int32 Index = 0; Index < SensesConfig.Num(); ++Index)
        {
           if (SensesConfig[Index] == nullptr)
           {
    	     continue;
            }
    
            if (SensesConfig[Index]->GetClass() == UAISenseConfig_Hearing::StaticClass())
            {
    	     UAISenseConfig_Hearing& hearingConfig = *Cast<UAISenseConfig_Hearing>(SensesConfig[Index]);
    	     hearingConfig.DetectionByAffiliation.bDetectEnemies = true;
    	     hearingConfig.DetectionByAffiliation.bDetectNeutrals = true;
    	     hearingConfig.DetectionByAffiliation.bDetectFriendlies = true;
             }
             else if (SensesConfig[Index]->GetClass() == UAISenseConfig_Sight::StaticClass())
             {
    	     UAISenseConfig_Sight* sightConfig = Cast<UAISenseConfig_Sight>(SensesConfig[Index]);
    	     sightConfig->DetectionByAffiliation.bDetectEnemies = true;
    	     sightConfig->DetectionByAffiliation.bDetectNeutrals = true;
    	     sightConfig->DetectionByAffiliation.bDetectFriendlies = true;
               }
          }
     }
    

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

Now, in your AIController class (I’m assuming you’re using a child class of AIController.h), add this line in the constructor:

//defined in parent class already, but never used. If you define your own, the Gameplay Debugger 
	//stops working
	//https://udn.unrealengine.com/questions/485016/view.html
	PerceptionComponent = CreateDefaultSubobject<UMyAIPerceptionComponent>("EnemyPerceptionComponent");	

Once the component you’re creating registers, it will trigger the previous code and it will override the flags for you.

See that comment? well, that’s a different problem I found in 4.21.2. Follow the link to understand see a complete explanation but, just so you know, AIController.h is already declaring PerceptionComponent and, if you add a perception component using your own variable (in your child class), you will run intro trouble.

Problems/Advantages of each solution:

  1. Solution 1: easy to implement, but everybody needs to remember to copy paste that string and have it around.
  2. Solution 2: Easy enough, but there’s a problem: if you use a variable (UPROPERTY) called PerceptionComponent in your base class, you will run into trouble because there’s a variable already called like that in AIController.h. I haven’t confirmed if, when you add an AIPerceptionComponent in Editor, is that the variable used by the Engine or if that variable stays as nullptr.
  3. Solution 3: implementation is not as fast as the other ones but you can create exposed variables to tweak the flags per AIController. Also, is automated, once you write the code, doesn’t matter how many senses your designer add in editor, they will just work. Notice that only Sight and Hearing are being checked. That’s because they are the only senses that uses the Affiliation flags in the Engine. If you add your custom senses and they use Affiliation flags too, you will have to add them to that loop. That’s the one I’m using right now. So far, so good.

I opened this thread whit other bugs I found in the perception system.
AI PErception Component Bug

Cheers!

The bug is still present in 4.23.1