Disable Player Controls From Server

Hello everyone,

I’m trying to disable player controls from the server to prevent a player from moving while being attacked in a combo. I’ve tried anchoring the HumanoidRootPart, but that leads to some side-effects that I don’t want to deal with.

The only other way that I know to disable player controls is through the PlayerModule. The problem is PlayerModule is located in Players/PlayerScripts which isn’t accessible from the server.

The only thing that I could think of is to use remotes to disable the controls from a LocalScript, but then the client would be able to prevent the server from disabling controls by ignoring the ClientEvent.

Is there a way that I can directly disable controls from the server without remotes?

3 Likes

There is no way to disable controls from the server, but if you want to disable movement can’t you just set the character’s Humanoid’s WalkSpeed and JumpPower/JumpHeight to 0?

1 Like

make a local script which disables movement, and make the local script fire upon a client event

2 Likes

Modifying player controls from the server is a hack and bad practice. Controls are client-sided, therefore the client should be authoritative of such controls. There’s the whole “don’t trust the client” yada yada whatever, but in the case of controls, the client has authority - you have to trust it.

Have the server inform the client that controls need to be disabled. When the client receives that message via RemoteEvent, then have it disable controls. Controls can be disabled in at least three different ways - changing DevXMovementMode, sinking input from ContextActionService or using the API exposed by PlayerModule (GetControls, then Disable on the returned object).

This topic has been brought up many times on the forums. Search around, you’ll find something.


@Natisb

They still want movement but not to allow players to use their own keys to move. In this case, this is a bad workaround. It doesn’t disable player controls, it prevents movement. OP only wants to disable controls, not movement altogether.

1 Like

I uncovered this in another forum post. From inside a localscript:

local ContextActionService = game:GetService("ContextActionService")
local FREEZE_ACTION = "freezeMovement"

-- to freeze
ContextActionService:BindAction(
    FREEZE_ACTION,
    function() return Enum.ContextActionResult.Sink end,
    false,
    unpack(Enum.PlayerActions:GetEnumItems())
)

--to unfreeze

ContextActionService:UnbindAction(FREEZE_ACTION)
1 Like

I’ve never heard of this, what is it and does it work?

You have to tell the client they can’t use their controls, but that doesn’t mean you have to trust them.

If you want the player to stand still and make sure they don’t cheat, just do sanity checks. The server could keep track of the player’s position. If it changes by a certain degree, the server could move them where they should be. This will prevent the vast majority of exploits.

@xBearByte

https://developer.roblox.com/en-us/api-reference/enum/DevComputerMovementMode
https://developer.roblox.com/en-us/api-reference/enum/DevTouchMovementMode


@Intended_Pun

That’s only if you’re looking to disable player controls and restrict movement to a certain area. In the case that you want players moving over great distances (e.g. cutscenes) but don’t want them using controls, this doesn’t fly as well or at all, since movement in a cutscene can easily be mistaken for player-sent movement and vice versa.

I’m not familiar with what kinds of exploiting tools are out there currently, but couldn’t an exploiter just ignore position replication for its character from the server? Or at least override replication once it receives it? Since the client’s character positions always replicate to the server, wouldn’t this be similar to simply asking the client to move into place?

Not if you constantly move them back. It would be a fruitless, never-ending loop for the exploiter.

Also @colbert2677, I see where you’re coming from, but I still can think of possible sanity checks even for long-distance cutscenes. It’s a cutscene; you always know where the player’s character should be, so you can plan accordingly. It would just be less straightforward.

Even then, I wouldn’t even use a player’s character for a cutscene in the first place. I would just clone it.

2 Likes

I made this:

local DisableClient = game.ReplicatedStorage.StopPlayerMovement
local EnableClient = game.ReplicatedStorage.ReturnPlayerMovement

Create a Variable for Each Script that i need to Stop the player movement but with Two only RemoteEvent in ReplicatedStorage.

ServerScript

DisableClient:FireClient(player)

LocalScript

local RE = game.ReplicatedStorage.StopPlayerMovement
--for Stop
RE.OnClientEvent:Connect(function(plr)
	local controls = require(game:GetService("Players").LocalPlayer.PlayerScripts.PlayerModule):GetControls()
	controls:Disable()
	
end)
local RE = game.ReplicatedStorage.ReturnPlayerMovement
--now for Return
RE.OnClientEvent:Connect(function(plr)
	local controls = require(game:GetService("Players").LocalPlayer.PlayerScripts.PlayerModule):GetControls()
	controls:Enable()

end)

I use two RemoteEvents because based on my script I would need indefinite times to return the player’s movement, so it’s much easier to take 2 RE to be able to use whenever you want :wink: .

3 Likes