AI perception swapping teams at runtime?

Hey, so what happens if in my custom code for the GetTeamAttitudeTowards() that I essentially changed the attitude towards another ai character based on what they were doing. Simplest analogy would be I have a benign PoliceAI and CitizenAI that are all on the same team or neutral, but if a Citizen is doing something illegal I want them to be considered on an Enemy team for the perception calculation only while they are performing an illegal action. This way I can use my PoliceAI perception code for catching these cases, otherwise I normally have CriminalAI for full on opposite teams, but I just wanted to be able to leverage the perception system for tracking and catching some citizen actions. Would this work? or is the Team stuff cached and only checked once? or only checked on enter/leave and is not constantly checked while ‘percieved’?

If not I guess I need to have my PoliceAI and CitizenAI on opposing teams, and in my Tick function

void APoliceAI::Tick(){
    TArray<AActor*> percieved;
    GetAIPerceptionComponent()->GetPerceivedHostileActors( percieved );
    for( AActor* actor : percieved )
    {
        // Check for illegal business
    }

Which I guess in the long run would not be ‘that much’ worse? I’m just figuring with the number of citizens an Early Cull would be better, but just not sure if the TeamAttitude would be the correct place to do so?

The AI perception component has its own tick interval so I would suggest to avoid getting the perceived actors in each tick and use the OnPerceivedActors function that is provided with the component itself. From what you’re describing it seems like you may be able to get away using a simple flag:

For example you can have a boolean property (maybe named bHasDoneSomethingIllegal which will be true in the end of certain actions) and your AI is perceiving an actor that has set the aforementioned flag to true can be considered as hostile. Although using this approach would require to check all the perceived actors instead of just the hostile ones.

Yeah was definitely preferable to be using the event fired on the perception change, but was worried the event would not be getting fired correctly if I was changing an AI team side while still within range of my AI perception. I am ‘assuming’ that the perception system would every frame regather all the AI controlled pawns and recheck their team every frame, then looping this group of opposing team members do the actual raycasts/range checks on their perception, or at least that’s what I am hoping for, but there may be some optimisations there for this to not be the case, was just hoping to find out if anyone knew.

Ok so to get the behaviour I want, I need to

void
APerceptionCharacter::BreakLawToggle()
{
    UAIPerceptionSystem* PerceptionSystem = UAIPerceptionSystem::GetCurrent( GetWorld() );
    am_breaking_law_ = !am_breaking_law_;
    PerceptionSystem->UnregisterSource( *this );
    PerceptionSystem->RegisterSource( *this );
}

And this will recheck the Team of the pawn, otherwise, it IS cached and will NOT detect my player if I have transient data that I am checking inside the GetTeamAttitudeTowards() it will simply ignore or always track my object dependent on what it was set to on spawn. Not sure how expensive this is, to register/deregister, but I think its probably cheaper than doing anything inside the tick.

1 Like