Need Help with Initializing AIPerception and getting enemy to switch players on the fly.

  1. I cannot for the life of me figure out how to get UAIPerceptionComponent to function in c++. This is how I Initialize it in the SZombieAIController.cpp but it never shows up on the AIController in the editor (yes the SZombieAIController.h is set up too).


#include "Perception/AIPerceptionComponent.h"

ASZombieAIController::ASZombieAIController(const class FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	PerceptionComponent = ObjectInitializer.CreateDefaultSubobject<UAIPerceptionComponent>(TEXT("PerceptionComp"));
	
	

}




  1. I have been banging my head on the wall trying to figure out how to get a zombie to update and change targets on the fly. I tried in blueprint because it was the only way to get the AIPerception to work but gave up and came back to C++ which I am more comfortable with. Basically I need to do this:

PsuedoCode



//should this be on Tick?

if(PlayersAreInLineOfSight) //using perception system?
{
//create an array of all players in Line of Sight
//Find the closest player to the zombie
//Set that as the enemy in the AI Behavior Tree
}
else
{
//create an array of all players in the game world
//Find the closest player to the zombie
//Set that players as the enemy in the AI Behavior Tree
}



The behavior tree has a moveto component that will move the zombie to the set target player.

So the above works in blueprint fine as long as you just want to search once. But what I need the zombie to do is constantly search for the player, update the player target, and move towards this new target. I assumed I could use eventTick but the problem I am having is that I am not sure the best way to abort out of the MoveTo in the behavior tree to update the new target (always moves towards the first target set). So I am moving back to C++ and once again trying to get things set up here.

So, to summerize, I need to:

1)Perceive players in LOS (Using PerceptionSystem)
2)Update the target
3)update which target to move to in the behavior tree.

There is something I am missing here (likely a decorator) but I am not sure what to do about it.

PS: There needs to be a ton more C++ AI tutorials that are relevant to 2016 and current versions of UE4. Right now its pretty pathetic.

I think you need to set up senses for the component, here is how i did it in my AI controller maybe it can help you.

.h



	virtual void ActorsPerceptionUpdated(const TArray<AActor*>& UpdatedActors);

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "AI")
        UAISenseConfig_Sight *sightConfig;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "AI")
	UAIPerceptionComponent *aiPerception;


.cpp



AUnitAIController::AUnitAIController(const FObjectInitializer &ObjInit)
{	
	aiPerception = GetAIPerceptionComponent();
	aiPerception = CreateDefaultSubobject<UAIPerceptionComponent>(TEXT("AIPerception Component"));
	sightConfig = CreateDefaultSubobject<UAISenseConfig_Sight>(TEXT("Sight Config"));
	sightConfig->DetectionByAffiliation.bDetectEnemies = true;
	sightConfig->DetectionByAffiliation.bDetectNeutrals = true;
	sightConfig->DetectionByAffiliation.bDetectFriendlies = true;
	aiPerception->ConfigureSense(*sightConfig);
}

void AUnitAIController::ActorsPerceptionUpdated(const TArray<AActor*>& UpdatedActors)
{
	for (AActor *actor : UpdatedActors)
	{
	     //do something
        }
}


The ActorsPerceptionUpdated is only called when something is changed (when characters enters or leaves your perception).

Thank you, any idea on how to update an AI’s target on the fly (as in while it is moving towards it’s original target)?

You could hold on to the pointer to the actor that you get in the UpdatedActors array and then update the target in OnTick. Or you could use a UPawnSensingComponent that is a kind of “simpler” version of the AIPerceptionComponent and has it’s own update interval, and do the stuff there.

I am in the process of moving my perception logic from my pawn to the AIController. I have it working fine on the pawn, but getting an error when I try to add a second sense when I came upon this.

I think the second line of this code wipes out the results of the first? I use the second line in my pawn where it works. But only the first line in my AIController.
aiPerception = GetAIPerceptionComponent();
aiPerception = CreateDefaultSubobject<UAIPerceptionComponent>(TEXT(“AIPerception Component”));

Trying to figure out why I get an accessviolation in the AIPerceptionComponent.cpp when I add the second sense.
PerceptionComp->ConfigureSense(*Sight);
PerceptionComp->ConfigureSense(*Hear); <—triggers the error.

This post helped me get on the right track.

Here’s how I setup the Perception inside my AIController class:

Create a Blueprint derived from your AIController, then add the PerceptionComponent inside that blueprint. If you configure your Pawn to use your Blueprint AIController, your Tasks, Services etc. can now in C++ access the Perception via aiController->GetPerceptionComponent() . The PerceptionComponent variable in the AIController class searches for all occurances of a UAIPerceptionComponent class, which includes blueprints.



void AAIController::PostRegisterAllComponents()
{
	Super::PostRegisterAllComponents();

	// cache PerceptionComponent if not already set
	// note that it's possible for an AI to not have a perception component at all
	if (PerceptionComponent == NULL || PerceptionComponent->IsPendingKill() == true)
	{
		PerceptionComponent = FindComponentByClass<UAIPerceptionComponent>();
	}
}