Modifiers target a specific node class and mutate that node's parameters before it ticks. See Concepts → Modifiers for the full lifecycle and resolution semantics; this page catalogs the shipped types.
UComposableCameraModifierBase¶
Abstract. Blueprintable.
The base class every modifier derives from. It has two members and expects subclasses (C++ or Blueprint) to fill them in:
| Member | Type | Purpose |
|---|---|---|
NodeClass |
TSubclassOf<UComposableCameraCameraNodeBase> |
Which node class this modifier targets. Set on the Class Default Object — do not edit per-instance. |
ApplyModifier(Node) |
BlueprintImplementableEvent |
Called once during activation with the matching node instance. Mutate the node's parameters here. |
The plugin does not ship any concrete subclasses — modifiers are entirely user-authored. See Extending → Custom Modifiers for the authoring recipe.
Non-transient cameras only
Modifiers can only be applied to non-transient cameras. A transient camera (activated with bIsTransient = true on FComposableCameraActivationParams) skips modifier resolution entirely. Cinematic intros and short-lived overlays are typical transient cameras — if you need them modifier-aware, clear bIsTransient.
UComposableCameraNodeModifierDataAsset¶
Concrete. The authoring wrapper.
A UDataAsset that groups one or more modifier instances together and attaches routing metadata. This is the unit you add and remove at runtime — individual modifier instances are not directly managed by the modifier manager.
| Field | Type | Purpose |
|---|---|---|
Modifiers |
TArray<UComposableCameraModifierBase*> (instanced) |
The modifier instances in this group. You can pack several modifiers targeting different node classes into one asset. |
OverrideEnterTransition |
UComposableCameraTransitionBase* (instanced) |
Transition used when this group reactivates the camera on add. Falls back to the camera's default transition if null. |
OverrideExitTransition |
UComposableCameraTransitionBase* (instanced) |
Transition used when this group reactivates the camera on remove. Falls back to the camera's default transition if null. |
CameraTags |
FGameplayTagContainer |
Gameplay tags identifying which cameras this group applies to. Only cameras whose tags match this container are affected. |
Priority |
int32 (≥ 0) |
When two groups both target the same node class for the same camera, the higher-priority group's modifier wins. |
Registered in the Content Browser under Composable Camera System → Node Modifier Data Asset with a purple color and a custom SVG thumbnail.
Why the wrapper¶
A modifier on its own is an instanced subobject — it can't live in the Content Browser and can't be referenced from multiple places. The data asset exists so designers can:
- Tune a modifier once in the asset and reference it from many Blueprints.
- Ship a library of preset gameplay effects (sprint FOV bump, aim-in pitch damping, stun shake) as named assets.
- Route via gameplay tags and priority without writing any gameplay code.
Priority — one group wins per (camera, node class)¶
When two UComposableCameraNodeModifierDataAssets both target the same camera (by gameplay tags) and both contain a modifier for the same NodeClass, only the higher-Priority group's modifier is active. This resolution happens in FComposableCameraModifierData::UpdateEffectiveModifiers each time the modifier set changes.
If you want additive behavior (sprint +10° FOV and zoom −5° FOV applied together), either:
- put both effects in a single modifier's
ApplyModifier(authored as one Blueprint event), or - split them into modifiers targeting different node classes — e.g.
FieldOfViewNodefor the FOV bump and a dedicatedZoomNodefor the zoom — so each wins its own class-level contest independently.
There is no stacking within a single NodeClass.
Camera tags — which cameras a group applies to¶
Every camera carries a FGameplayTagContainer (declared on its type asset). When a modifier group's CameraTags container is non-empty, the modifier manager only considers the group for cameras whose tags match.
- Empty
CameraTags→ "applies to all cameras". Use sparingly. - One or more tags → "applies only to cameras with any of these tags". Standard usage.
Tag matching is via FGameplayTagContainer::HasAny, not HasAll — a group tagged Gameplay.ThirdPerson matches any camera that carries Gameplay.ThirdPerson in its tag set, even if the camera carries additional tags.
Enter/exit transition overrides¶
When adding or removing a modifier group causes a reactivation (because the effective modifier for some node class changed on the running camera), the reactivation uses a transition resolved through:
- If adding →
OverrideEnterTransitionon the incoming group, if set. - If removing →
OverrideExitTransitionon the outgoing group, if set. - Otherwise → the five-tier resolution chain, starting from the target camera's
EnterTransition.
This gives modifier authors a surgical tool for "when this effect is added/removed, blend differently than the camera's default" — without forcing a table entry or a caller-supplied override at every activation site.
UComposableCameraModifierManager¶
Runtime manager, owned by the PCM. Not user-facing.
The manager maintains:
ModifierData— the map ofFGameplayTag → TMap<NodeClass, TArray<FModifierEntry>>, holding every active modifier indexed by camera tag and node class.EffectiveModifiers— the computed map ofNodeClass → FModifierEntryfor the currently running camera, representing whatever wins the per-node-class priority contest.
Two public entry points drive the manager:
void AddModifier(UComposableCameraNodeModifierDataAsset* ModifierAsset);
void RemoveModifier(UComposableCameraNodeModifierDataAsset* ModifierAsset);
Both funnel through UpdateEffectiveModifiers, which returns a (bChanged, Transition*) pair. If bChanged is true, the PCM triggers a reactivation using the returned transition.
Gameplay code should always go through UComposableCameraBlueprintLibrary::AddModifier / RemoveModifier rather than poking the manager directly — the library takes the world-context object and a resolved AComposableCameraPlayerCameraManager* (fetch it once via GetComposableCameraPlayerCameraManager) and forwards to the right manager.
See also: Concepts → Modifiers, Extending → Custom Modifiers, Blueprint API → Modifiers.