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.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/.