Lock-on

Lock the camera and body on the most relevant enemy, switch targets with a key, and break the lock when the target dies, leaves or goes out of sight.

Source: module-kits:kits/combat_lockon/usage/en.mdView Markdown source

Also read offline — CLI: grip-forge docs combat-lockonMCP tool: gripforge_docs { "topic": "combat-lockon" }

Target lock-on (combat.lockon) #

What it is for #

combat.lockon is the lock of action games: the player presses lock_on and the most relevant enemy becomes the target. A candidate is a living entity that carries one of targetTags, none of ignoreTags, stands within maxDistance and inside the cone acquireAngle in front of the camera; the nearest comes first. lock_next moves the lock around the player. While it holds, the free-look camera turns toward the target and the body keeps facing it, so the character strafes around it. The lock breaks on death, disappearance, distance, loss of sight (a ray through the physics port) or by hand. Even without a camera kit the lock still names a target for other kits (an aim, a HUD). The kit has no presentation.

Turn it on #

gripforge_gamekit_install   { project_id: "gkp_…", id: "combat.lockon" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "combat.lockon",
                              config: { "maxDistance": 18, "breakDistance": 24, "relock": false } }

It requires game.engine and input.actions. Optional companions: character.third_person (free look and body facing), combat.core (a candidate must be alive for combat.health) and enemy.ai (its enemies carry the enemy tag).

First example #

<!-- test: kits/combat_lockon/tests/combat_lockon.rs::locking_takes_the_nearest_enemy_in_front_and_tells_it --> A player at the origin looks along +z. Two enemies stand about 3 m and 9 m ahead. lock takes the nearest, locked is true, the variables follow and one lockon.acquired event is emitted. Locking again on the same target is true and silent.

{ "service": "combat.lockon", "method": "lock", "args": [] }
{ "service": "combat.lockon", "method": "target", "args": [] }

lock answers true; target answers the id of the nearest enemy. lockon.active is true, lockon.target is that id and lockon.distance is its distance rounded to a tenth of a metre.

Settings and defaults #

SettingDefaultMeaning
maxDistance18Metres: a candidate must be this close to be locked.
breakDistance24Metres: the lock breaks (reason distance) beyond this; never below maxDistance.
acquireAngle150Degrees of the cone in front of the camera for the first lock (360: any direction).
lineOfSighttrueA target hidden behind a collider for sightGrace seconds breaks the lock (reason sight).
sightGrace1.5Seconds a target may stay out of sight.
targetTags["enemy"]An entity with any of these tags is a candidate.
ignoreTags["dead", "player"]An entity with any of these tags is never a candidate.
cameraFollowtrueTurn the free-look camera toward the target while locked.
cameraSpeed6How fast the camera turns, per second (0 snaps).
strafetrueThe body keeps facing the target.
relockfalseWhen the target dies or leaves, lock the next candidate at once.

All are moddable.

Services, events, variables #

  • Service combat.lockon: target(), locked(), lock(entity?) (a named entity must be a living enemy in reach; none: the best candidate), unlock(reason?), next(direction?) (1 or -1 moves around the player; without a lock it locks), candidates() (nearest first) and yawTo().
  • Events lockon.acquired (entity, target, distance), lockon.switched (entity, from, to), lockon.lost (entity, target, reason: manual, distance, sight, dead or gone). The kit listens to entity.despawned and combat.killed.
  • Variables lockon.active, lockon.target, lockon.distance.
  • Actions lock_on (default keys Mouse1 and Tab, gamepad button 11: locks, or releases when pressed again) and lock_next (KeyC, gamepad button 15: switches).
  • Script verbs lockon_lock { target? }, lockon_release and the condition lockon_locked { target? }.

Hooks and modding #

HookMutableEffect
lockon.acquiretargetThe player is about to lock a target among candidates; name another entity (a boss the story wants first) or cancel: no lock, lock answers false.
lockon.losenoneThe lock is about to break for reason; cancelled for distance or sight the lock holds; ignored for manual, dead and gone.

Engines #

Web and the native player (Rust); the kit has no Godot, Unity or Unreal adapter.

When it does not do what you expect #

  • Nothing locks: the candidate has no targetTags, has an ignoreTags tag (a dead enemy), is farther than maxDistance, or is outside the cone; try acquireAngle: 360.
  • The lock breaks at once: breakDistance is reached, or the target is behind a collider for longer than sightGrace.
  • The camera does not turn: character.third_person free look is not installed or cameraFollow is false.

Limits #

One lock, for the player. No target indicator is drawn here: read lockon.target from your HUD.

Versions #

Kit 1.0.0. Requires game.engine 1 and input.actions 1.