Skip to main content

The state machine

        RequestMount                    attach                RequestDismount       detach
None ─────────────► Entering ────────────────► Seated ─────────────────► Exiting ────────► None
▲ │ ▲ │
│ │ │ attach │
└── rollback ───────────┘ └──── Shuffling ◄───────┘
(server said no) RequestChangeSeat

EEDMountPhaseNone, Entering, Seated, Shuffling, Exiting. One enum, on one replicated property.

Why one enum and not six booleans

Mounting systems commonly spread the same information over bIsMounted, bIsSeated, bIsAttached, bIsDriver and a pair of action enums. Those can contradict each other, and do: a rider whose montage is interrupted stays bIsMounted with no seat, forever. One enum cannot disagree with itself.

The three moments

Every transition has the same shape, whether it is driven by a montage or by the procedural slide.

1. Start

The seat is reserved — nobody else can take it — the phase is published, and the local animation begins on every machine that can see the rider.

A seat therefore has three states, not two: free, reserved, occupied. Without the middle one, two players who press the key on the same frame both pass "is it free", both play a get-in, and one ends up standing inside the other.

2. The midpoint

The rider attaches, or detaches. Driven by:

  • a Mount.Event.Attach / .Detach notify, when the montage has one;
  • a fraction of the montage's length, when it does not;
  • the watchdog, when the montage was cut short.

Occupancy changes here, on the authority. A shuffle releases the old seat and takes the new one in the same step, so there is never a frame where the rider holds both, and never one where they hold neither.

3. The end

The phase settles to Seated or None.

The watchdog

Montages get interrupted — by damage, by a slot conflict, by a Blueprint playing something else on the same slot. A transition that waits forever for a notify that will never come leaves the rider mid-air with no collision and no input.

Transition Watchdog Grace (1.5 s by default) completes the transition as if the notify had fired. Finishing late is always better than not finishing.

Reading the phase

Rider->GetMountPhase();      // the enum
Rider->IsMounted(); // anything but None
Rider->IsSeated(); // Seated exactly
Rider->IsTransitioning(); // Entering, Exiting or Shuffling

From Blueprint, and from an anim graph, the same answers are available without a cast through UEDMountingLibrary: Get Mount Phase, Is Seated, Is Driving Mount, Get Seat Role.

OnMountPhaseChanged fires on every machine, including simulated proxies, so a HUD or an anim graph reacting to it needs no replication of its own.

Requests and refusals

Every request returns an FEDMountResult. When bSuccess is false, Failure says why:

FailureMeaning
NoMountableNull target, or no mountable component.
MountDisabledIt has one, but it is switched off.
NoSeatNo seat matched, or the mount has none.
SeatOccupiedThe seat asked for is taken, and fallback was not allowed.
SeatLockedThe seat's rider tag query refused this rider.
TooFarBeyond the mount's interaction distance.
NoEntryPointEvery way in is obstructed.
NoExitPointEvery way out is obstructed, and the unsafe fallback is off.
BusyAlready entering, exiting or shuffling. One transition at a time.
WrongStateNonsense for the current phase — dismounting on foot, for instance.
NoRiderThe actor has no rider component.
ServerRejectedThe server refused what the client predicted.
DeniedGame code said no, through CanAcceptRider.

UEDMountingLibrary::GetFailureText turns any of them into localised text you can put on screen.

Half of these are things a game wants to react to differently: a locked seat plays a rattle, a full one prints "no room", too far does nothing at all. That is why the API returns a reason rather than a boolean.

Transition modes

EEDTransitionMode, per rider, defaulting to the project's setting:

Mode
AutoMontage when one resolves, procedural when none does. The default.
Montage OnlyAlways a montage. Warns and falls back to instant when none resolves.
Procedural OnlyAlways the slide, even when a montage exists. Useful for debugging alignment.
InstantAttach on the same frame. For spawning already-seated, and for cutscenes.

Auto is what makes the framework work the moment you add two components. Systems that only support the montage path are unusable until someone has authored six animations, which is why so many mount setups never get past the prototype where everyone teleports into the car.