How-To: Make an Actor a Team Agent
Goal: give an actor team membership the right way for your project - and, for AI, make sure perception can actually read its attitude.
Prerequisites
CrimsonTeams enabled (Quick Start).
1. Add the component (pick one path)
| Path | When to use |
|---|---|
| Default subobject on a base class | Your own characters/NPCs that must always have a team - guaranteed present, no setup |
| `UGFA_AddTeams` (Game Feature) (CrimsonCore - requires all Crimson plugins) | Data-driven assignment of teams/tags to actor classes from a mode or faction Game Feature, no base-class edit. Ships in CrimsonCore; without it, use the default-subobject or Add Component path above |
| Add Component in a Blueprint | One-off or designer-placed actors |
Both at once is safe
UGFA_AddTeams (CrimsonCore - requires all Crimson plugins) find-or-configures: if the actor already has a component (e.g. a default subobject) it applies the configured tags to it instead of adding a duplicate, and on deactivation removes only the tags it added. So a base-class subobject and a GFA can coexist.2. Set its tags
Set Team Tags / Hostile To Tags in the Details panel for static actors, or mutate at runtime on the server. The full mutation set:
| Team tags | Hostile-to tags |
|---|---|
JoinTeam(tag) / LeaveTeam(tag) | AddHostileTags(c) / RemoveHostileTags(c) |
AddTeamTags(c) / RemoveTeamTags(c) | SetHostileTags(c) |
SetTeamTags(c) | - |
// NPC faction setup, server-side (Team is this NPC's UCrimsonTeamAgentComponent):if (HasAuthority()){const FGameplayTag Bandit = FGameplayTag::RequestGameplayTag(FName("Team.Bandit"));const FGameplayTag Player = FGameplayTag::RequestGameplayTag(FName("Team.Player"));Team->JoinTeam(Bandit);Team->AddHostileTags(FGameplayTagContainer(Player));}
3. (AI) Expose attitude to perception
Unreal's AI perception reads attitude by casting the perceiving actor (the AI's controller or pawn) to IGenericTeamAgentInterface - it never looks at the component. So for affiliation-filtered senses to see Crimson teams, the AI's controller (or pawn) must implement the interface and forward to the tag logic.
// On your AI controller (or pawn):virtual ETeamAttitude::Type GetTeamAttitudeTowards(const AActor& Other) const override{// Resolve via the controlled pawn, where the team component usually lives.return UCrimsonTeamStatics::GetTeamAttitudeBetween(GetPawn(), &Other);}
Using CrimsonCore? Already done
ACrimsonCharacter, ACrimsonNPCBase, the AI controllers, and ACrimsonPlayerState already implement this forward, so perception reads Crimson attitudes out of the box. The component ships too, as a default subobject - on ACrimsonPlayerState for players, and on ACrimsonNPCBase / ACrimsonCompanionBase / ACrimsonSummonBase / ACrimsonPawn for the rest - so a GFA_AddTeams only needs to set tags. You only need the manual steps above when you write your own classes.Verify
An affiliation-filtered AI Perception (Sense Sight set to detect Enemies) sees an actor whose tags make it hostile, and ignores a friendly one.
See also
- Concept: Dynamic Attitude & Multiplayer - why the interface-on-actor rule exists, and how changes propagate
- API Reference - the full component surface