local Players = game:GetService("Players") local RunService = game:GetService("RunService") local UserInputService = game:GetService("UserInputService") local player = Players.LocalPlayer local playerScripts = player:WaitForChild("PlayerScripts") local controls = require(playerScripts:WaitForChild("PlayerModule")):GetControls() local BIND_NAME = "CameraAlignedMobileMove" local DEADZONE = 0.05 local SNAP_THRESHOLD = 0.3 local humanoid local function getHumanoid() local character = player.Character or player.CharacterAdded:Wait() return character:WaitForChild("Humanoid") end local function unbind() RunService:UnbindFromRenderStep(BIND_NAME) end local function flatUnit(vector) local flat = Vector3.new(vector.X, 0, vector.Z) return flat.Magnitude > 0 and flat.Unit or Vector3.zero end local function snap(x, z) local sx = math.abs(x) > SNAP_THRESHOLD and (x > 0 and 1 or -1) or 0 local sz = math.abs(z) > SNAP_THRESHOLD and (z > 0 and 1 or -1) or 0 local vector = Vector3.new(sx, 0, sz) return vector.Magnitude > 0 and vector.Unit or Vector3.zero end local function hookCharacter(character) unbind() humanoid = character:WaitForChild("Humanoid") if not UserInputService.TouchEnabled then return end RunService:BindToRenderStep(BIND_NAME, Enum.RenderPriority.Input.Value + 1, function() if not humanoid or not humanoid.Parent then unbind() return end local camera = workspace.CurrentCamera if not camera then return end local move = controls:GetMoveVector() if move.Magnitude <= DEADZONE then return end local forward = flatUnit(camera.CFrame.LookVector) local right = flatUnit(camera.CFrame.RightVector) if forward == Vector3.zero or right == Vector3.zero then return end local snapped = snap(move.X, move.Z) local finalMove if snapped ~= Vector3.zero then finalMove = (right * snapped.X) - (forward * snapped.Z) else finalMove = (right * move.X) - (forward * move.Z) end if finalMove.Magnitude > 0 then humanoid:Move(finalMove.Unit, false) end end) end player.CharacterAdded:Connect(hookCharacter) if player.Character then hookCharacter(player.Character) else humanoid = getHumanoid() end RunService.RenderStepped:Connect(function() if UserInputService.TouchEnabled then return end if not humanoid or not humanoid.Parent then return end local camera = workspace.CurrentCamera if not camera then return end local move = humanoid.MoveDirection if move.Magnitude < 0.1 then return end local forward = flatUnit(camera.CFrame.LookVector) local right = flatUnit(camera.CFrame.RightVector) if forward == Vector3.zero or right == Vector3.zero then return end local x = move:Dot(right) local z = move:Dot(forward) local snapped = snap(x, z) if snapped == Vector3.zero then return end local finalMove = (right * snapped.X) + (forward * snapped.Z) if finalMove.Magnitude > 0 then humanoid:Move(finalMove.Unit, false) end end)