Camera Abilities
CrimsonCore exposes the CrimsonCamera features - shoulder swap, zoom, aim/ADS, recenter, and lock-on - as input-driven Gameplay Abilities. They are granted and bound through the normal UCrimsonAbilitySet + UCrimsonInputConfig path, exactly like Jump, Sprint, and Crouch.
UCrimsonGameplayAbility for UCrimsonAbilitySystemComponent's input and activation-group logic to manage it, and these abilities bridge CrimsonCamera + CrimsonInput + the lock-on component. The Cardinal Rule reserves that cross-plugin glue for CrimsonCore - CrimsonCamera ships the camera modes and lock-on components; CrimsonCore turns them into abilities.What ships
Seven abilities, all deriving from UCrimsonCoreGameplayAbility (or its UCrimsonGameplayAbility_BindNativeInput axis subclass). Camera is a per-player concern, so they run on the owning client only - nothing replicates except Aim's Status.Aiming activation tag.
| Ability | Input | What it does |
|---|---|---|
UCrimsonGameplayAbility_CameraShoulder | Tap | Swaps (or sets) the camera's shared shoulder side. bToggle (default) swaps L/R; set bToggle = false + TargetShoulder to force a side. |
UCrimsonGameplayAbility_CameraZoom | Axis (float) | Dollies the camera in/out by axis * ZoomSpeed (the shared zoom). Always-on input handler - binds its action on spawn. |
UCrimsonGameplayAbility_CameraAim | Hold | Pushes AimCameraMode while held; breaks any active lock-on; shoulder + zoom are shared camera-wide and carry over automatically; grants Status.Aiming. |
UCrimsonGameplayAbility_CameraRecenter | Tap | Swings the active mode to behind the character once. |
UCrimsonGameplayAbility_LockOnToggle | Toggle / Hold | Acquires a lock on activation and stays active for the lifetime of the lock, granting Status.LockedOn. Ends on a second press / release, or when the lock breaks externally (distance / LoS / target death). |
UCrimsonGameplayAbility_LockOnSwitchTarget | Axis (Vector2D) | Switches the lock-on target toward a screen-space direction (e.g. a right-stick flick). The component throttles repeats via its switch deadzone + cooldown. |
UCrimsonGameplayAbility_LockOnCyclePoint | Tap | Steps to the next/previous lock point on the current target (Direction). |
"Active mode" means whatever camera mode is currently driving the view - third-person, aim, or lock-on, all of which derive from UCrimsonCameraMode_ThirdPerson. Shoulder and zoom are shared on UCrimsonCameraComponent, so those abilities set them once on the component and every mode reflects them. Recenter is per-mode, so it acts on GetActiveCameraMode() and no-ops gracefully when the active mode is not a third-person subclass (e.g. a pure top-down mode).
Shoulder & zoom carry-over
Shoulder and zoom live on UCrimsonCameraComponent as a single shared value, not on each mode instance - so switching modes carries your framing automatically. Releasing Aim (or breaking Lock-On) keeps your current shoulder and zoom with no save/restore. See CrimsonCamera -> Concept: Shared Camera State.
bUseShoulderOffset = false / bUseZoom = false on that camera mode so it ignores the shared values.Driving the camera mode from your own ability
UCrimsonCoreGameplayAbility exposes two BlueprintCallable ways to set a camera mode while an ability is active - usable from a C++ override or a Blueprint ability graph:
| Helper | Behavior |
|---|---|
PushOverrideCameraMode(Mode, OwnerTag) / PopOverrideCameraMode() | Pushes onto the camera component's tag-keyed override stack (LIFO). Composes with other overrides (lock-on) and wins over the per-frame default selection. Popped automatically on EndAbility. This is what Aim uses, keyed by Camera.Mode.Aim. |
SetCameraMode(Mode) / ClearCameraMode() | The legacy single-slot path (via UCrimsonHeroComponent::AbilityCameraMode). Lower priority than the override stack - use only for exclusive, non-stacking cases. |
PushOverrideCameraMode, not SetCameraMode.void UMyAimAbility::ActivateAbility(...){Super::ActivateAbility(...);// Composes with the override stack; auto-popped on EndAbility.PushOverrideCameraMode(AimCameraMode, CrimsonGameplayTags::Camera_Mode_Aim);}
In Blueprint, the same two pairs are nodes on any ability deriving from Crimson Core Gameplay Ability: Push Override Camera Mode / Pop Override Camera Mode and Set Camera Mode / Clear Camera Mode. Get Camera Component From Actor Info returns the avatar's camera component, and Get Active Camera Mode (on it) returns the mode currently driving the view.
Setup
- Create a data-only Blueprint subclass of each ability you want (e.g.
GA_CameraAim). For Aim, setAimCameraModeto aUCrimsonCameraMode_ThirdPersonsubclass with aim framing (tighter FOV / fixed shoulder); for Zoom, tuneZoomSpeed; for Shoulder, choosebToggleor a fixedTargetShoulder. - Add them to a `UCrimsonAbilitySet` referenced by your
UCrimsonPawnData::AbilitySets- the same set that grants Jump / Sprint. - Map input in your
UCrimsonInputConfig: add anAbilityInputActionsrow binding anIA_*to each camera input tag. Zoom expects a 1D Axis action and Switch-Target a 2D Axis action; the rest are digital. - Add the lock-on components for the lock-on abilities: the player needs a
UCrimsonLockOnComponentwith aUCrimsonLockOnConfigassigned, and lockable actors need a lock-on target component.ACrimsonCharacteralready carries a lock-on component plus a lockable target component (PvP);ACrimsonNPCBasecarries a lockable target component. See the CrimsonCamera docs for the targeting preset + config setup.
CrimsonCoreTags.h: InputTag.Camera.Aim, InputTag.Camera.Shoulder, InputTag.Camera.Zoom, InputTag.Camera.Recenter, InputTag.Camera.LockOn, InputTag.Camera.LockOn.Switch, InputTag.Camera.LockOn.CyclePoint. The Aim ability's override is keyed by Camera.Mode.Aim and its activation tag is Status.Aiming.IMC_CrimsonCore_Movement's look-stick mapping sets AimingStateTag to Status.Aiming on its UCrimsonInputModifierGamepadSensitivity. While Aim is held, the player's Aim Sensitivity preset replaces Look Sensitivity for the right stick, and it reverts on release. Lock-on does not count as aiming - only this ability grants the tag.Behavior notes
ClearLockOn() - the two are mutually exclusive states by design. If you want them to coexist, adjust the Aim ability so it leaves the lock-on override in place beneath the aim override.Status.LockedOn (ActivationOwnedTags). Gate other behavior with it: add it to ActivationBlockedTags / ActivationRequiredTags on discrete abilities, or do a HasMatchingGameplayTag(Status.LockedOn) check inside always-on look / input handlers (which don't re-activate per frame). The tag is local - lock-on is client-local and not replicated, so it gates local concerns like camera / input; server-authoritative gating would need the lock state replicated.NetExecutionPolicy = LocalOnly; Aim is LocalPredicted so Status.Aiming replicates for server-side / remote reactions. Each client aims and locks independently - no camera state is replicated.Plugins/CrimsonCore/Source/CrimsonCore/Public/Abilities/Camera/ (+ matching .cpp under Private/Abilities/Camera/). Base helpers + tags: Public/Abilities/CrimsonCoreGameplayAbility.h, Public/CrimsonCoreTags.h. Camera modes + lock-on components: Plugins/CrimsonCamera/Source/CrimsonCamera/Public/.