I’m just starting out and learning UE5. I discovered that switching the play mode to “Play as Client” with 2 players completely disables the character pawn movement when Constain to Plane is active. I’ve made a short video that shows this using a basic Third Person example project and only changing a few things:
Number of Players = 2
Net Mode = Play as Client
Constrain to Plane = ON
Plane Cnstrtain Normal = 0 1 0
When this is done, attempting to move the pawn (using normal inputs) locks it in place as if the server were denying movement ability.
Hi, you’re not missing anything obvious—this is a known quirk of how CharacterMovement behaves with networking.
What’s happening here is that “Constrain to Plane” is applied locally, but movement authority still comes from the server. When you run in “Play as Client”, the client tries to move the character along the constrained plane, but the server doesn’t necessarily have the same constraint state (or applies it differently). As a result, the server rejects or corrects the movement, which makes it look like the pawn is completely stuck.
A few things to check / try:
Make sure the constraint is applied on the server as well
If you’re enabling “Constrain to Plane” in Blueprint or at runtime, ensure it runs on both server and client (or just on the server). The server must have the same plane constraint settings (PlaneConstraintNormal = (0,1,0) in your case).
Set it in defaults instead of at runtime
If possible, enable “Constrain to Plane” directly in the CharacterMovement component defaults. This ensures both server and client start with identical settings.
Check replication / authority flow
If you’re modifying movement settings in BeginPlay, make sure it’s not running client-only. Use HasAuthority() or run it via a Server RPC if needed.
Test with “Play as Listen Server”
If it works there but not in “Play as Client”, that’s a strong sign it’s a server/client state mismatch rather than input or setup error.
Optional workaround
You can explicitly call: CharacterMovement->SetPlaneConstraintEnabled(true); CharacterMovement->SetPlaneConstraintNormal(FVector(0,1,0));
on the server to guarantee consistency.
In short: the movement isn’t actually “disabled”—it’s being constantly corrected by the server due to mismatched constraint settings. Once both sides agree on the plane constraint, movement should work normally.
If it still reproduces even with server-side setup, it might be worth reporting as a bug along with your repro steps, since this edge case can be a bit inconsistent across versions.
This is not the first post I have seen of you plugging someone’s question into Chat GPT and just pasting the answer. That’s pretty ingenuine. Most of your post uses terminology like “If possible” or “or applies it differently” because the AI doesn’t actually know, it’s giving best guesses. These types of replies I have seen you post on multiple questions are not really helping the original poster.
This is a very obvious copy paste from ChatGPT. The dashes give it way from the start the “In short” part also gives it away as well as the first sentence. AI doesn’t know how the engine works because it can’t look at the source code it gives only assumptions and guesses based on the internet and their answers (which from what I can find no one has posted about this). This doesn’t help the OP at all since it’s a possible misdirection.
If I had to guess it’s because the CharacterMovementComponent doesn’t replicate constraining to a plane correctly. I’d start by inspecting what the component does when that is enabled. You could also manually do it by having the server correct to 0 on the plane you do not want to move on. This might be easier for you.