How-To: Add Soft Lock-On
Goal: enable action-combat soft lock-on (Black Desert / Aion-style). The camera stays fully player-controlled, and whenever you are not hard-locked the system continuously tracks the screen-center-most valid enemy and exposes it so your attacks can face / home toward it.
UCrimsonLockOnComponent and a UCrimsonLockOnConfig whose targeting preset selects candidates). Soft lock gathers through that preset by default - but read the callout below first: soft needs a preset that culls what's behind the camera.Toggle Lock On commits the current soft target instantly. Soft resumes when the hard lock is released.TargetingPreset (soft reuses it), or author a dedicated UCrimsonLockOnConfig -> SoftTargetingPreset (its own, typically tighter cone) - when set, soft gathers through it instead of the hard preset. Keep the filter's Require In Front Of Source on (default): with Camera View the cone apex is the camera, so this half-space test also culls targets beside/behind the player that still sit inside the camera's cone. The Preset tab of Crimson.Camera.DevTools flags a soft preset that is missing this filter.1. Enable it (per project)
Soft lock is opt-in. Turn it on and tune the feel under Project Settings -> Crimson -> Crimson Camera -> Soft Lock-On.
| Setting | Effect |
|---|---|
bEnableSoftLock | Master gate. Off by default - nothing tracks until a developer opts in. |
SoftStickinessScoreMargin | How much better a challenger must score (0..1 screen-center proximity) before it steals the current soft target. Higher = stickier. |
SoftMinDwellTime | Minimum seconds the current soft target is held before any switch (a target that leaves the cone/range drops immediately regardless). |
SoftLockMaxDistance | Range cap (cm); 0 reuses the config's MaxLockDistance. |
SoftLockRefreshInterval | Seconds between re-evaluations (the target is not recomputed every frame). |
bShowSoftTargetIndicator | Show a light marker on the current soft target so the player can tell who they'll hit (drives the widget's new SoftTarget state). |
2. Consume the target in gameplay
The camera plugin only exposes the target; turning the character or homing an attack is gameplay. Query Get Current Lock On Target - it returns the hard target if locked, otherwise the soft target - as an FCrimsonLockOnTargetInfo (actor + bone component + socket + world location + bIsHardLock).
On your attack ability / actor, call Get Current Lock On Target on the UCrimsonLockOnComponent, branch on the return bool, then use World Location (motion-warp / homing) or Target Actor (rotate to face). Subscribe to On Soft Target Changed to react when the pick changes.
FaceControlRotation faces the target. Prefer FaceControlRotation over FaceControlRotationSmoothly: the smooth mode goes through PhysicsRotation, which Character Movement skips during anim root motion, so it does nothing inside a root-motion attack montage. For facing that is independent of the camera, feed the world location from Get Current Lock On Target to Motion Warping instead.(CrimsonCore - requires all Crimson plugins) For orientation: CrimsonCore wraps this for gameplay abilities as the Pawn Facing While Active ability extension (
UCrimsonCoreAbilityExtension_PawnFacing) and the UCrimsonCoreAbilityCameraStatics library (Get Current Lock On Target, Push/Pop Override Camera Mode for an ability). It also installs a lock-on warp-target provider on its pawns.3. (Optional) Gentle camera assist
By default the camera is untouched (authentic action-combat feel). To add a subtle assist that keeps the soft target loosely framed, set SoftLockCameraBehavior to Gentle Camera Assist, make a Blueprint child of UCrimsonCameraMode_SoftLockOn, assign it to SoftLockCameraModeClass, and give it a SoftLockCameraOwnerTag distinct from your hard-lock CameraOwnerTag.
DeadzoneAngleDeg - and only toward the deadzone edge. A player pushing the stick always wins. Tune DeadzoneAngleDeg, SoftBiasInterpSpeed, and MaxBiasDegreesPerSec on the mode.SoftLockCameraOwnerTag. If it matches your hard-lock CameraOwnerTag the two collide - the plugin refuses to push it and logs a warning. Give soft lock its own tag (e.g. Camera.Mode.SoftLockOn).Crimson.Camera.DevTools: the Lock-On tab shows soft state and what Get Current Lock On Target resolves to (HARD vs SOFT), the Targets tab adds a per-actor Soft column plus a magenta soft-target debug draw, and the Preset tab inspects the soft preset side-by-side with the hard one.See also
- How-To: Set Up Lock-On - the hard lock-on this builds on.
- Concept: Lock-On Pipeline - targeting, hard vs soft, and how they interact.
- Lock-On Reference (in API Reference) - the soft API, the info struct, and the settings.