# Getting in and out of vehicles (vehicle.enter_exit) Part of the vehicle family: see the [vehicles guide](guide:vehicles) for the cars themselves. ## What it is for Lets the player get into a car and out of it. It moves the character of `character.control` onto the driver seat of a `vehicle.driveable` car, hands the controls to the car, and puts the character back on foot next to the door. With `vehicle.doors` installed, the entry is a sequence: walk to the door, open it, sit, close it, then drive; the exit is the reverse. Without doors, or with `animatedTransitions` off, the seat is taken at once. A car that does not carry the owned tag is reported as stolen on entry, which a wanted-level kit can count. ## Turn it on ```text gripforge_gamekit_install { project_id: "gkp_…", id: "vehicle.enter_exit" } gripforge_gamekit_install { project_id: "gkp_…", id: "vehicle.doors" } gripforge_gamekit_configure { project_id: "gkp_…", id: "vehicle.enter_exit", config: { "entryDuration": 1.4, "enterRadius": 3.5, "ownedTag": "player_owned" } } ``` It requires `character.control`, `vehicle.drive`, `interaction.use`, `physics.port` and `game.engine`. The animated entry needs a humanoid character and the entry sockets of the car (`Entry_*` and `Seat_*` of the model, or the `seat` component below). ## First example With `{ "animatedTransitions": false }`, a player next to a car calls `enter(car)` on `vehicle.enter` and gets `true`. After a few ticks, `exit()` on `vehicle.exit` also answers `true`. If a wall stands on the side the `exitOffset` prefers, the character reappears on the free side of the car and never inside the wall. ## Settings and defaults | Setting | Default | Meaning | |---|---|---| | `animatedTransitions` | `true` | With `vehicle.doors`: approach, open, sit, close before driving. Off: immediate seat transfer | | `entryDuration` | 1.65 | Seconds to lower onto the seat after the door opens (0.8 to 4) | | `exitDuration` | 1.5 | Seconds to step out after the door opens (0.8 to 4) | | `enterRadius` | 3 | Distance in metres at which a car becomes interactive (1 to 8) | | `exitOffset` | `[1.6, 0, 0]` | Local offset where the character reappears on exit; the kit checks the sides with `physics.port` | | `ownedTag` | `player_owned` | A car with this tag is not reported as stolen | Leaving is refused above 1.25 m/s. Driving input is locked during a sequence, and a save during it keeps its phase. A committed seat sets `refs.vehicle` on the player and its tags, and the sequence publishes simple pose data in `vehicle.occupant`. ## Services, events, hooks - `vehicle.enter` (service): `enter(vehicle)` puts the player in a car or starts its door sequence, and returns `false` when out of reach, taken, wrecked or refused; `driving()` returns `{ player, vehicle }` while seated, else `null`; `transition()` returns the sequence in progress or `null`; `setAccess(vehicle, anchors)` sets the entry sockets of a car, `false` when invalid. - `vehicle.exit` (service): `exit()` lets the player out next to the door; `false` when not seated, too fast or refused. - `vehicle.entry.started` (event): the entry was accepted, input is locked, the player is not driving yet. Payload `{ entity, vehicle }`. - `vehicle.entered` (event): the player took the driver seat. Payload `{ entity, vehicle, stolen, sequenced }`. - `vehicle.exited` (event): the player stands outside again. Payload `{ entity, vehicle, at, ejected, sequenced }`; `ejected` is true when the car was wrecked or removed under the player. - `vehicle.enter.refused`, `vehicle.exit.refused` (events): a tap cancelled the entry or the exit, payload `{ entity, vehicle, reason }`. Never emitted without a tap. - Listens to `interaction.requested`, `input.action`, `vehicle.spawned`, `vehicle.destroyed` and `entity.despawned`. | Hook | Payload | What a tap may do | |---|---|---| | `vehicle.enter` | `{ entity, vehicle, seat, stolen, sequenced }` | change `stolen`, or cancel (a locked car): nobody moves. Asked once, when the entry is accepted, before anything moves | | `vehicle.exit` | `{ entity, vehicle, speed }` | cancel: the player stays seated. Not asked when the player is ejected | In game.engine content, a car instance can carry the component `seat`: `{ owned?, access? }`, where `access` holds `door`, `entry`, `seat`, `wheel`, `feet` and `ceiling` sockets. The mission steps `enter_vehicle`, `exit_vehicle` and `deliver_vehicle` are provided. ## Hooks and modding ```json { "id": "no_exit_at_speed", "hook": "vehicle.exit", "if": [{ "field": "speed", "op": ">", "value": 8 }], "cancel": true, "reason": "too_fast" } ``` Every setting is moddable. ## Engines Web and the native player run the same Rust logic, including the door sequence. Godot, Unity and Unreal deliver it with the character animation played through their own animation systems (or a pose interpolation without a clip). ## When it does not do what you expect | Symptom | Cause and fix | |---|---| | The player cannot get in | farther than `enterRadius`, the car is a wreck or taken, the speed is above 1.25 m/s, or a tap refused | | The entry is instant | `vehicle.doors` is not installed or `animatedTransitions` is `false` | | The character pops through the wall on exit | `physics.port` is missing, so the exit sides are not checked | | The car is reported stolen | it lacks the `ownedTag` tag; add it or set `owned` in `seat` | ## Limits One driver seat. No passengers, and no NPC driver sequence in this kit. ## Versions Kit 1.5.1: the hooks `vehicle.enter` and `vehicle.exit` and the component `seat`; the sequenced entry with `vehicle.doors` arrived in 1.3.0.