What does "Listener must have a valid id to update its sense config" mean?

The message comes from UAIPerceptionSystem::OnListenerConfigUpdated() when you call UAIPerceptionComponent::ConfigureSense() can pass in a sense object such as an instance of UAISenseConfig_Sight.

The problem here is that the UAIPerceptionComponent member variable PerceptionListenerId is invalid, its never been changed from the -1 set in the constructor.

When things go well, the PerceptionListenerId is set in UAIPerceptionComponent::OnRegister() in the line

AIPerceptionSys->UpdateListener(*this);

However in 5.4.2 this line is only called if there is at least one Sense associated with the UAIPerceptionComponent, like this:

if (SensesConfig.Num() > 0)
{
	// set up perception listener based on SensesConfig
	for (auto SenseConfig : SensesConfig)
	{
		if (SenseConfig)
		{
			RegisterSenseConfig(*SenseConfig, *AIPerceptionSys);
		}
	}

	AIPerceptionSys->UpdateListener(*this);
}

UAIPerceptionComponent::OnRegister() is called after the containing actors constructor is called but before any implementation of OnPossess() is called. So if the setup for the AI sense is done like this:

void ASpawnEnemyAIController::OnPossess(APawn* InPawn)
{
	Super::OnPossess(InPawn);

	AISenseConfig_Sight->SightRadius = SightRange;
	AISenseConfig_Sight->LoseSightRadius = (SightRange + 20.0f);
	AISenseConfig_Sight->PeripheralVisionAngleDegrees = 120.f;
	AISenseConfig_Sight->DetectionByAffiliation.bDetectEnemies = true;
	AISenseConfig_Sight->DetectionByAffiliation.bDetectNeutrals = true;
	AISenseConfig_Sight->DetectionByAffiliation.bDetectFriendlies = true;

	AIPerceptionComponent->ConfigureSense( *AISenseConfig_Sight );
	AIPerceptionComponent->SetDominantSense(AISenseConfig_Sight->GetSenseImplementation());
    ...
}

it will not work. The senses must have been configured (by a call to ConfigureSense()) in the actor's constructor, so to make this work move this line:

AIPerceptionComponent->ConfigureSense( *AISenseConfig_Sight );

to the constructor. The rest of the lines can remain in OnPossess().

Feedback

Please leave any feedback about this article here