Design the enter/exit system for drivable vehicles in a multiplayer Unreal Engine game. A player on foot can walk up to a vehicle, get in, drive it, and later get out at a sensible exit position. While driving, the player's input must control the vehicle rather than the character, and the on-foot character must not be lost — its inventory and state have to survive the trip so the same character resumes on exit. The session is networked, so who controls what must be authoritative and consistent for all clients, and a client must not be able to grant itself control of a vehicle. Driving and on-foot movement should both replicate smoothly. Describe how you model the player, character, and vehicle, how control transfers on enter and exit, what happens to the character while driving, where authority lives, and the trade-offs of your approach.
Make the vehicle its own APawn; on enter the server calls Controller->Possess(Vehicle) and hides the character Pawn. On exit it re-possesses the character and teleports it to an exit point. The server is authoritative over every Possess call.
- ✗Calling
Possesson the client instead of the server, breaking authority - ✗Attaching the character to the vehicle instead of swapping the possessed Pawn
- ✗Destroying or replacing the player's
Controllerinstead of re-possessing
- →How would you handle multiple seats — driver plus passengers — in one vehicle?
- →What happens to the character Pawn while the player is driving, and why?
Key classes
AVehiclePawn— anAPawn(orAWheeledVehiclePawn) with movement and seats.ACharacter— the player's normal on-foot character.APlayerController— one per player; possesses the character or the vehicle in turn.UVehicleInteractionComponent— on the vehicle: trace/overlap for entry zones, seat list.FSeatData— aUSTRUCT: seat socket, occupancy, exit point.
Data model
Both the character and the vehicle are APawn. The controller is not destroyed — it only changes its Possess target. The vehicle holds an array of FSeatData; the character is hidden on entry (SetActorHiddenInGame, collision off), not destroyed.
Data flow
- The player near the vehicle presses "enter" → Server RPC
ServerEnterVehicle(Vehicle, Seat). - The server checks distance and seat availability.
- The server hides the
ACharacterand callsController->Possess(Vehicle). - Input now goes to the
AVehiclePawn; movement replicates like any Pawn. - Exit → a Server RPC; the server calls
Possess(Character), teleports the character to an exit point, and shows it.
Replication considerations
Possess is called only on the server — possession is authority-driven and replicates automatically. Seat occupancy state is Replicated for UI and checks. Hiding the character replicates via bHidden. Vehicle movement uses standard Pawn replication with client prediction.
Designer-facing config
Seats, their sockets, and exit points are an FSeatData array in the vehicle's details. Entry distance and required tag are DataAsset fields. A new vehicle = a new Blueprint from AVehiclePawn.
Trade-offs
- Swapping
Possessvs. attaching the character: swappingPossessis cleaner for input and replication; attaching suits passengers who do not drive. - Hiding the character vs. destroying it: hiding preserves inventory and state; destroying requires a full restore on exit.