Alright so I am working on a game that requires me to remake the movement system roblox already has. W goes forward, A goes left, S goes backwards, D goes right.
What’s the issue? I got it working but once you turn around 180 degrees your character starts bugging out. I think its because the axis goes from xyz to zyx. Any fix for this? I am using Humanoid:Move(). You can see in the video below;
local UserInputService = game:GetService('UserInputService')
local RunService = game:GetService('RunService')
local Players = game:GetService('Players')
local Character = Players.LocalPlayer.Character or Players.LocalPlayer.CharacterAdded:Wait()
local Humanoid = Character:FindFirstChild('Humanoid')
local TypingInChat = false
UserInputService.InputBegan:Connect(function(Key)
if TypingInChat then return end
if Key.KeyCode == Enum.KeyCode.W then
while UserInputService:IsKeyDown(Enum.KeyCode.W) do
RunService.PreRender:Wait()
if UserInputService:IsKeyDown(Enum.KeyCode.S) then
Humanoid:Move(Vector3.new(Humanoid.MoveDirection.x, 0, 0), false)
else
Humanoid:Move(Humanoid.MoveDirection - Vector3.new(0, 0, 1), false)
end
end
end
if Key.KeyCode == Enum.KeyCode.S then
while UserInputService:IsKeyDown(Enum.KeyCode.S) do
RunService.PreRender:Wait()
if UserInputService:IsKeyDown(Enum.KeyCode.W) then
Humanoid:Move(Vector3.new(Humanoid.MoveDirection.x, 0, 0), false)
else
Humanoid:Move(Humanoid.MoveDirection + Vector3.new(0, 0, 1), false)
end
end
end
if Key.KeyCode == Enum.KeyCode.D then
while UserInputService:IsKeyDown(Enum.KeyCode.D) do
RunService.PreRender:Wait()
if UserInputService:IsKeyDown(Enum.KeyCode.A) then
Humanoid:Move(Vector3.new(0, 0, Humanoid.MoveDirection.z), false)
else
Humanoid:Move(Humanoid.MoveDirection + Vector3.new(1, 0, 0), false)
end
end
end
if Key.KeyCode == Enum.KeyCode.A then
while UserInputService:IsKeyDown(Enum.KeyCode.A) do
RunService.PreRender:Wait()
if UserInputService:IsKeyDown(Enum.KeyCode.D) then
Humanoid:Move(Vector3.new(0, 0, Humanoid.MoveDirection.z), false)
else
Humanoid:Move(Humanoid.MoveDirection - Vector3.new(1, 0, 0), false)
end
end
end
if Key.KeyCode == Enum.KeyCode.Space then
while UserInputService:IsKeyDown(Enum.KeyCode.Space) do
RunService.PreRender:Wait()
Humanoid.Jump = true
end
end
end)
I’m pretty sure the problem is it is moving based on the direction of the character, not the camera. Try moving the character based on the direction of the camera instead.
Example:
Humanoid:Move(camera.CFrame.LookVector) -- for moving forward
-- Services
local UserInputService = game:GetService('UserInputService')
local RunService = game:GetService('RunService')
local Players = game:GetService('Players')
-- Types
type Direction = {
key: Enum.KeyCode,
vector: Vector3
}
type Command = () -> ()
-- Player and Character
local player = Players.LocalPlayer
local Character = player.Character or player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild('Humanoid')
-- Flags
local TypingInChat: boolean = false
-- Command Factory
local function moveCommand(direction: Direction): Command
return function()
while UserInputService:IsKeyDown(direction.key) do
RunService.PreRender:Wait()
Humanoid:Move(direction.vector, true)
end
end
end
-- Directions and Commands
local directions: {Direction} = {
{key = Enum.KeyCode.W, vector = Vector3.new(0, 0, -1)},
{key = Enum.KeyCode.S, vector = Vector3.new(0, 0, 1)},
{key = Enum.KeyCode.D, vector = Vector3.new(1, 0, 0)},
{key = Enum.KeyCode.A, vector = Vector3.new(-1, 0, 0)},
{key = Enum.KeyCode.Space, vector = Vector3.new(0, 1, 0)}
}
local commands: {[Enum.KeyCode]: Command} = {}
for _, direction in ipairs(directions) do
commands[direction.key] = moveCommand(direction)
end
-- Input Handling
UserInputService.InputBegan:Connect(function(input: InputObject, gameProcessed: boolean)
if gameProcessed or TypingInChat then return end
local command: Command? = commands[input.KeyCode]
if command then
command()
end
end)
The Move Player function causes the player’s character to walk in the given direction until stopped, or interrupted by the player (by using their controls).
This is useful when scripting NPC Humanoids that move around a map - but are not controlled by an actual player’s input.
Note that the function’s second argument indicates whether the provided Vector3 should move the player relative to world coordinates (false) or the player’s Camera (true).
This function causes the Humanoid to walk in the given Vector3 direction.
By default, the direction is in world terms, but If the relativeToCamera parameter is true, the direction is relative to the CFrame of the CurrentCamera. As the negative Z direction is considered “forwards” in Roblox, the following code will make the humanoid walk in the direction of the CurrentCamera.