05-03-26
Smooth Analog Movement Script
This Lua script for Rebind hardware input converts discrete WASD key presses into smooth analog-style movement, providing a more natural and gamepad-like feel. Configure smoothing duration for desired
rebindlua scriptanalog movementwasdsmoothinghardware inputscript
Question
Movement keys to analog-style smoothing
Rebind AI
Movement Keys to Analog-Style Smoothing
This script converts discrete WASD key presses into smooth analog-style movement, useful for games that support analog input or for creating gamepad-like feel from keyboard controls.
luau
-- rebind: min_sdk=0.1.0
-- rebind: name=Movement Smoothing
-- rebind: description=Convert WASD to smooth analog movement
local cfg = UI.Schema({
enabled = UI.Toggle(true, { label = "Enable" }),
smoothing = UI.Slider(100, { min = 10, max = 200, suffix = "ms", label = "Smoothing Duration" }),
keys = UI.Text("WASD", { label = "Movement Keys", maxLength = 10 }),
})
local movements = {
W = { x = 0, y = -1 },
A = { x = -1, y = 0 },
S = { x = 0, y = 1 },
D = { x = 1, y = 0 },
}
local activeKeys = {}
local movementTask = nil
local function updateMovement()
if movementTask and movementTask:IsRunning() then
movementTask:Cancel()
end
movementTask = Run(function()
local startTime = System.Time()
local duration = cfg.smoothing
while true do
local elapsed = System.Time() - startTime
local progress = math.min(elapsed / duration, 1.0)
local totalX = 0
local totalY = 0
for key, _ in pairs(activeKeys) do
if movements[key] then
totalX = totalX + movements[key].x
totalY = totalY + movements[key].y
end
end
if totalX == 0 and totalY == 0 then
break
end
local easeProgress = progress * progress * (3 - 2 * progress)
HID.Move(totalX * easeProgress, totalY * easeProgress)
Sleep(16)
if progress >= 1.0 then
startTime = System.Time()
end
end
end)
end
function OnDown(key)
if not cfg.enabled or not movements[key] then
return true
end
activeKeys[key] = true
updateMovement()
return false
end
function OnUp(key)
if not cfg.enabled or not movements[key] then
return true
end
activeKeys[key] = nil
updateMovement()
return false
end
function OnStop()
if movementTask and movementTask:IsRunning() then
movementTask:Cancel()
end
end
function OnBlur()
activeKeys = {}
if movementTask and movementTask:IsRunning() then
movementTask:Cancel()
end
endHow It Works
Smooth Acceleration:
- Tracks which movement keys are currently held
- Continuously interpolates from current position to target position over the configured duration
- Uses an ease-in-out curve (smoothstep) for natural acceleration/deceleration
Multi-Directional Support:
- Combines active key vectors (e.g., pressing W+D creates diagonal movement)
- Cancels opposing directions (A+D = stationary)
- Updates smoothly when keys are pressed or released
Performance:
- Runs in a coroutine to avoid blocking input processing
- 16ms per frame (~60fps smooth movement)
- Only active when keys are held
Configuration:
smoothing: Duration in milliseconds for acceleration/deceleration (100ms = responsive, 200ms = floaty)enabled: Toggle on/off without reloading