I’m trying to write my own VR movement and such for my own game, but I’m having an issue where when moving the joystick back and forth, the player model kinda sticks and moves very slowly forwards and backwards. However, moving left and right works perfectly.
Video (sorry about the weird graphical bugs, OBS is acting funny): Watch 2025-08-08 19-48-42 | Streamable
I couldn’t find much online, and I was hesitant about asking ChatGPT but even it was useless (maybe for the best, too). There’s a good chance that the player model itself is the problem as well, but given my limited knowledge on scripting and the fact I haven’t done it in so long, a bug seems very well likely.
VRService = game:GetService("VRService")
RunService = game:GetService("RunService")
UserInputService = game:GetService("UserInputService")
ContextActionService = game:GetService("ContextActionService")
Player = game.Players.LocalPlayer
Character = Player.Character or Player.CharacterAdded:Wait()
Root = Character:WaitForChild("HumanoidRootPart")
Humanoid = Character:WaitForChild("Humanoid")
Camera = workspace.CurrentCamera
LeftHand = Character:WaitForChild("LeftHand")
RightHand = Character:WaitForChild("RightHand")
MoveSpeed = 10
TurnSpeed = math.rad(90)
CameraYaw = 0
CanJump = true
local function blockInput(_, inputState, _)
return Enum.ContextActionResult.Sink
end
ContextActionService:BindAction("BlockLeftClick", blockInput, false, Enum.KeyCode.ButtonL3)
ContextActionService:BindAction("BlockRightClick", function(actionName, inputState, inputObject)
if inputState == Enum.UserInputState.Begin then
local rightX, rightY = 0, 0
local gamepadState = UserInputService:GetGamepadState(Enum.UserInputType.Gamepad1)
for _, input in ipairs(gamepadState) do
if input.KeyCode == Enum.KeyCode.Thumbstick2 then
rightX, rightY = input.Position.X, input.Position.Y
end
end
local humanoidState = Humanoid:GetState()
local groundedStates = {
Enum.HumanoidStateType.Running,
Enum.HumanoidStateType.Landed,
Enum.HumanoidStateType.RunningNoPhysics
}
local IsGrounded = false
for _, state in ipairs(groundedStates) do
if humanoidState == state then
IsGrounded = true
break
end
end
if rightY > 0.8 and CanJump and IsGrounded then
CanJump = false
Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
end
if inputState == Enum.UserInputState.End then
CanJump = true
end
return Enum.ContextActionResult.Sink
end, false, Enum.KeyCode.ButtonR3)
ContextActionService:BindAction("BlockThumbstick2Move", blockInput, false, Enum.KeyCode.Thumbstick2)
RunService.RenderStepped:Connect(function(dt)
local gamepadState = UserInputService:GetGamepadState(Enum.UserInputType.Gamepad1)
local rightX, rightY = 0, 0
local leftX, leftY = 0, 0
for _, input in ipairs(gamepadState) do
if input.KeyCode == Enum.KeyCode.Thumbstick1 then
leftX, leftY = input.Position.X, input.Position.Y
elseif input.KeyCode == Enum.KeyCode.Thumbstick2 then
rightX, rightY = input.Position.X, input.Position.Y
end
end
if math.abs(leftX) > 0.1 or math.abs(leftY) > 0.1 then
local forward = Vector3.new(math.sin(CameraYaw), 0, math.cos(CameraYaw))
local right = Vector3.new(math.cos(CameraYaw), 0, -math.sin(CameraYaw))
local moveDir = (forward * leftY) + (right * leftX)
if moveDir.Magnitude > 0 then
moveDir = moveDir.Unit
Root.CFrame = Root.CFrame + moveDir * MoveSpeed * dt
end
end
if math.abs(rightX) > 0.1 then
CameraYaw = CameraYaw - rightX * TurnSpeed * dt
end
local camPos = Root.Position + Vector3.new(0,5,0)
Camera.CFrame = CFrame.new(camPos) * CFrame.Angles(0, CameraYaw, 0)
local LHTrack = VRService:GetUserCFrame(Enum.UserCFrame.LeftHand)
local RHTrack = VRService:GetUserCFrame(Enum.UserCFrame.RightHand)
LeftHand.CFrame = Camera.CFrame * LHTrack
RightHand.CFrame = Camera.CFrame * RHTrack
end)