local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local rootPart = character:WaitForChild("HumanoidRootPart")
local humanoid = character:WaitForChild("Humanoid")
-- Configuration
local ROTATION_SPEED = 15 -- How snappy the turn feels
-- Mapping keys to directions
local directions = {
Forward = {Vector3.new(0, 0, -1), Enum.KeyCode.W},
Backward = {Vector3.new(0, 0, 1), Enum.KeyCode.S},
Left = {Vector3.new(-1, 0, 0), Enum.KeyCode.A},
Right = {Vector3.new(1, 0, 0), Enum.KeyCode.D},
}
local function getMoveDirection()
local moveVec = Vector3.new(0, 0, 0)
-- Check keyboard input
if UserInputService:IsKeyDown(directions.Forward[2]) then moveVec += directions.Forward[1] end
if UserInputService:IsKeyDown(directions.Backward[2]) then moveVec += directions.Backward[1] end
if UserInputService:IsKeyDown(directions.Left[2]) then moveVec += directions.Left[1] end
if UserInputService:IsKeyDown(directions.Right[2]) then moveVec += directions.Right[1] end
-- Normalize to prevent faster diagonal movement
if moveVec.Magnitude > 0 then
return moveVec.Unit
end
return moveVec
end
RunService.RenderStepped:Connect(function(dt)
local inputDir = getMoveDirection()
if inputDir.Magnitude > 0 then
-- Calculate the target CFrame (Look rotation)
local targetLook = CFrame.new(rootPart.Position, rootPart.Position + inputDir)
-- Smoothly interpolate the rotation
rootPart.CFrame = rootPart.CFrame:Lerp(targetLook, dt * ROTATION_SPEED)
end
end)