Possession
Input redirection to server entities (vehicles / mind-control / GM drive) via Movement's seam.
Services you call 1
Crossplay implements these. Resolve them from DI and call them from your own systems.
IPossessionService
Redirect a session's movement input to a server entity. SERVER game code decides when (vehicle seat, mind control, GM tools) — there is no client request path. One controller per entity, one entity per controller; everything releases automatically on entity removal or disconnect.
-
bool Possess(ISession session, long entityId)Points the session's movement input at a server entity (its own avatar stays parked where it was). The client is told via PossessionChanged.
-
bool Release(ISession session)Returns control to the session's own avatar (pushes PossessionChanged{0}).
-
bool TryGetPossessed(ISession session, out long entityId)The entity the session currently possesses, if any.
Wire messages 1
The protocol this piece speaks. Ids are allocated per piece so they can never collide.
PossessionChanged Server → client: this session's movement input now drives EntityId (0 = back to its own avatar). SERVER game code decides possession (vehicle seat, mind control, GM drive); the client repoints its camera/HUD — presentation is 100% the game's.
Unity services you inject 1
Crossplay binds these in the client context. Inject and call them from your own MonoBehaviours and presenters.
IPossessionClient
The Possession piece, client side: which entity does my input drive right now? The game repoints its camera/HUD on ControlChanged (0 = back to the own avatar) and should suspend client-side prediction while possessing — the possessed entity is server-authoritative like any NPC.
-
long ControlledEntityIdThe possessed entity id (0 = controlling the own avatar).
-
event Action<long> ControlChangedRaised when the server changes what this session controls.
UI views you can replace 1
Each ships a working uGUI panel you can drag into a scene. Substitute your own view to keep the logic and change the look — the presenter never knows.
ICrossplayPossessionView
Narrow contract the presenter drives. UI-only and intent-free: Possession has NO client request path (the wire is one server-push message), so this view only renders — it never sends.