How would I make a player only be able to walk backwards?

One way I can think of doing it would be to have the WalkSpeed set to 0, but when you are pressing down ‘S’ (or the other device equivalents) it sets your WalkSpeed to 16 or whatever you want it to be.

1 Like

1). in the Characters’ humanoid there is an “AutoRotate” property, just set it to false

2). Disable the Key that moves the player forward

2 Likes

I spent about two minutes quickly testing my idea, here it is if you want it (just put it in a localscript in StarterCharacter or StarterGui)

local Player = game.Players.LocalPlayer
local InputKey = "S"

repeat wait() until Player.Character
local Humanoid = Player.Character:WaitForChild("Humanoid")

Humanoid.WalkSpeed = 0

local UserInputService = game:GetService("UserInputService")

UserInputService.InputBegan:connect(function(UserInput, GameProcessedEvent)
	if UserInput.UserInputType == Enum.UserInputType.Keyboard then
        if not GameProcessedEvent then
			if UserInput.KeyCode == Enum.KeyCode[InputKey] then
				Humanoid.WalkSpeed = 16
			elseif UserInput.KeyCode == Enum.KeyCode["W"] then
				Humanoid.WalkSpeed = 0
			end
		end
	end
end)

UserInputService.InputEnded:connect(function(UserInputEnded, GameProcessedEvent)
	if UserInputEnded.UserInputType == Enum.UserInputType.Keyboard then
       	if not GameProcessedEvent and UserInputEnded.KeyCode == Enum.KeyCode[InputKey] then
			Humanoid.WalkSpeed = 0
		end
	end
end)
1 Like

This does check out, although there is one fatal flaw.

Users can manipulate this by pressing A and D while walking backwards, although this is obviously a given considering you didn’t code with this in mind. (I’m also not sure if this flaw is actually preventable?)

Not too sure on a fix.
I’m open to any and all ideas.

You can easily do the same with what I did for when you press W, that you can’t press A or D either, I spent another minute configuring my code for ya.

local Player = game.Players.LocalPlayer
local InputKey = "S"

repeat wait() until Player.Character
local Humanoid = Player.Character:WaitForChild("Humanoid")

Humanoid.WalkSpeed = 0

local UserInputService = game:GetService("UserInputService")

local movingSideways = false

UserInputService.InputBegan:connect(function(UserInput, GameProcessedEvent)
	if UserInput.UserInputType == Enum.UserInputType.Keyboard then
        if not GameProcessedEvent then
			if UserInput.KeyCode == Enum.KeyCode[InputKey] and not movingSideways then
				Humanoid.WalkSpeed = 16
			elseif UserInput.KeyCode == Enum.KeyCode["W"] then
				Humanoid.WalkSpeed = 0
			elseif UserInput.KeyCode == Enum.KeyCode["A"] then
				movingSideways = true
				Humanoid.WalkSpeed = 0
			elseif UserInput.KeyCode == Enum.KeyCode["D"] then
				movingSideways = true
				Humanoid.WalkSpeed = 0
			end
		end
	end
end)

UserInputService.InputEnded:connect(function(UserInputEnded, GameProcessedEvent)
	if UserInputEnded.UserInputType == Enum.UserInputType.Keyboard then
       	if not GameProcessedEvent then
			if UserInputEnded.KeyCode == Enum.KeyCode[InputKey] then
				Humanoid.WalkSpeed = 0
			elseif UserInputEnded.KeyCode == Enum.KeyCode["A"] then
				movingSideways = false
			elseif UserInputEnded.KeyCode == Enum.KeyCode["D"] then
				movingSideways = false
			end
		end
	end
end)

EDIT: Forgot one thing.

1 Like

This works great!

I am curious to see whether any other ideas come through, so I won’t mark this as a solution just yet.

I’d like to see if there are any other methods that anyone has in mind, or if anyone else’s methods evolve at all.

Thank you, though!
I greatly appreciate your input. (hehe that kinda sounds like a pun)

2 Likes

I had to fix a little glitch so this is the final code, let me know if you want me to explain anything (:

local Player = game.Players.LocalPlayer
local InputKey = "S"

repeat wait() until Player.Character
local Humanoid = Player.Character:WaitForChild("Humanoid")

Humanoid.WalkSpeed = 0

local UserInputService = game:GetService("UserInputService")

local movingSidewaysA, movingSidewaysD  = false, false

UserInputService.InputBegan:connect(function(UserInput, GameProcessedEvent)
	if UserInput.UserInputType == Enum.UserInputType.Keyboard then
        if not GameProcessedEvent then
			if UserInput.KeyCode == Enum.KeyCode[InputKey] and not movingSidewaysA and not movingSidewaysD then
				Humanoid.WalkSpeed = 16
			elseif UserInput.KeyCode == Enum.KeyCode["W"] then
				Humanoid.WalkSpeed = 0
			elseif UserInput.KeyCode == Enum.KeyCode["A"] then
				movingSidewaysA = true
				Humanoid.WalkSpeed = 0
			elseif UserInput.KeyCode == Enum.KeyCode["D"] then
				movingSidewaysD = true
				Humanoid.WalkSpeed = 0
			end
		end
	end
end)

UserInputService.InputEnded:connect(function(UserInputEnded, GameProcessedEvent)
	if UserInputEnded.UserInputType == Enum.UserInputType.Keyboard then
       	if not GameProcessedEvent then
			if UserInputEnded.KeyCode == Enum.KeyCode[InputKey] then
				Humanoid.WalkSpeed = 0
			elseif UserInputEnded.KeyCode == Enum.KeyCode["A"] then
				movingSidewaysA = false
			elseif UserInputEnded.KeyCode == Enum.KeyCode["D"] then
				movingSidewaysD = false
			end
		end
	end
end)
2 Likes

Come to think of it, was adding movingSidewaysA / D actually needed?

I’m sure they’d both just provide the same use.

Would keeping it just as movingSideways not heed the same outcome?

2 Likes

You need it because otherwise you can hold down A, then D, release D which would cause the code to count it that you aren’t moving sideways, so then you would be holding A still and then when you press W you would be able to move diagonally. It is very much needed to prevent that bug.

2 Likes

Ohh yeah, that makes more sense now.

Thanks for the clarification on that.

1 Like

With yours, if you hold S, then hold A, then release S, then hold S again (so you’re now holding A and S) you can move diagonally.

Gif: https://gyazo.com/c6eec36fa0d567c2c087e7c82ae79f5d

1 Like

You can do this in far less lines and in a supported manner. Instead of modifying the character’s walk speed, go after the actual control bindings themselves.

local ContextActionService = game:GetService("ContextActionService")
local REMOVE_BINDS = {"moveForwardAction", "moveLeftAction", "moveRightAction"}

for _, actionBinding in ipairs(REMOVE_BINDS) do
    ContextActionService:UnbindAction(actionBinding)
end
6 Likes

Hello and thank you for your response!

I’ve actually started development on the short game I’m making based on this.

I’m marking this now as the solution as it is shorter and generally more efficient - users can spam all their movement keys while walking backward and not suddenly stop if they were walking backward and pressed A or D or W, which was a flaw of the other script.

Thanks for your help and sorry for replying late!

Hello, if you don’t mind me asking, how would you rebind these actions?

That code works with the expectation that you won’t rebind the actions during the game again, because there isn’t a way to fetch the relevant functions other than through the PlayerModule itself.

If you find yourself with a case of needing to enable and disable player movement on the fly, I recommend that you sink items of the PlayerActions Enum. Assuming it still works as well, requiring the PlayerModule, calling GetControls and then Disable should do the trick as well.

What I need to do is just disable movement sideways and backwards for a bit then re enable, how would I do that in lets say a local script which I fire a remote to from the server, what im doing is firing that remote when i want the effects to take place and then again when i want the movement to return to normal. so how would i do all of that in a local script

Bind a sink for CharacterLeft, CharacterRight and CharacterBackward PlayerActions when you want to disable movement and unbind it when you want to reenable movement in those directions. The articles and search queries linked in my post should help point you towards the means of doing this - you can use those to assemble your system together.

How would I do the bindings exactly? Im kinda new to that contextplayeraction thingz and I saw u need to pass a handle function thingy and set a priority number and i have no idea what to do basically when it comes to creating these binds

ok I figured out how to do it but there is an issue, for some reason it stops every action made before it executes, is there a way for it to not do that? so for if an example i have w held down the char will walk forward even after that change without me having the click again? image

2 Likes

While this may have been marked as solved years ago, the marked solution only forces players using a keyboard to move backwards. This means it won’t force players using a phone or controller to move only backwards. Here’s a solution that would force players to move only backwards on all devices:

-- This will only work if this LocalScript is located here:
-- StarterPlayer > StarterCharacterScripts

local Player = game.Players.LocalPlayer
local Camera = workspace.CurrentCamera

local PlayerScripts = Player:WaitForChild("PlayerScripts", 10)
local PlayerModule = PlayerScripts and PlayerScripts:WaitForChild("PlayerModule", 10)
local Controls = if PlayerModule then require(PlayerModule).controls else nil

game:GetService("RunService").PreAnimation:Connect(function(dt)	
	local currentMoveVector = Controls:GetMoveVector()
	if currentMoveVector.Magnitude<=0 then
		return
	end
	
	local modifiedMoveVector = Vector3.new(0, 0, math.max(0, currentMoveVector.Z))
	local currentCameraOrientation = Vector3.new(Camera.CFrame:ToOrientation())

	Player:Move(CFrame.fromOrientation(0, currentCameraOrientation.Y, currentCameraOrientation.Z):VectorToWorldSpace(modifiedMoveVector))
end)

Here’s a short video of what this solution looks like:

There’s also a free model version of the solution that uses attributes to limit the move direction. They can be used to do stuff like preventing the player from moving backwards: Simple Walk Restrictions - Roblox

2 Likes