AI's Identity Crisis: When Enemies Turn on Each Other| Author: Antony Castro| Posted on: July 24, 2025


During this week's development sprint, I encountered a critical bug: our AI enemies were engaging in unexpected friendly fire. Instead of focusing their aggression solely on the player, they would occasionally turn their weapons on their own comrades, leading to chaotic and unintended attacks among the enemies.

This problem severely impacted the core gameplay loop. Not only did it break immersion by making the enemies appear confused and disorganized, but it also inadvertently made the game easier for the player, as the AI was effectively thinning its own numbers. This undermined the challenge we aimed for and wasted valuable AI processing on irrelevant targets, creating a frustrating and unpredictable experience for anyone trying to engage in meaningful combat.

The root cause of this "AI identity crisis" stemmed from how our AI's perception and targeting systems were configured. Our AAIC_CodeEnemyController was correctly detecting pawns within its sight radius, but it lacked a mechanism to differentiate between hostile targets (the player) and friendly units (other enemies). Essentially, any APawn within range was considered a potential target.

To solve this, I implemented Unreal Engine's IGenericTeamAgentInterface and utilized FGenericTeamId. This powerful system allows us to assign a numerical team ID to any AActor or AController that implements the interface, enabling robust team-based logic for AI perception.

Here's how I addressed it:

Team ID Assignment:

In our ABaseCharacter class (which both ABasePlayer and ACodeBaseEnemy inherit from), I added a FGenericTeamId TeamID property. By default, I set TeamID to 0 for all characters.

For the player, in the ABasePlayer class, I explicitly set TeamID to 1 in the Blueprint. This clearly distinguishes the player as a separate team.

AI Controller Configuration:

In the AAIC_CodeEnemyController's constructor, I configured the UAISenseConfig_Sight component. I set DetectionByAffiliation.bDetectEnemies = true, while ensuring bDetectFriendlies = false and bDetectNeutrals = false. This tells the AI to only consider actors from a different team as valid targets.

Crucially, in AAIC_CodeEnemyController::OnPossess(), I ensured that the AI controller's TeamID was correctly set based on the TeamID of the pawn it was possessing.

By implementing FGenericTeamId, our AI now intelligently differentiates the player. Enemies only perceive and engage targets that are not on their team, ensuring they focus their attacks on the player. This simple yet effective solution has dramatically improved the AI's behavior, making combat more logical, challenging, and ultimately, a much more enjoyable experience for the player.

Get Operation Nightfall

Leave a comment

Log in with itch.io to leave a comment.