
Key Required

local UserInputService = game:GetService("UserInputService")
local LocalPlayer = game.Players.LocalPlayer
local moveSpeed = 10 -- studs per second (constant speed)
local yOffset = 15 -- studs to move up
local zigzagAmplitude = 1 -- studs for zigzag offset
local zigzagFrequency = 1 -- number of zigzags per waypoint
local verticalMoveSpeed = 10 -- studs per second for vertical ascent/descent
local isMoving = false
local moveCoroutine = nil
local function smoothVerticalMove(character, startY, targetY, speed)
local currentCFrame = character:GetPivot()
local currentPos = currentCFrame.Position
local distance = math.abs(targetY - startY)
local travelTime = distance / speed
local startTime = tick()
while tick() - startTime < travelTime do
if not isMoving then
return false
end
local alpha = (tick() - startTime) / travelTime
local newY = startY + (targetY - startY) * alpha
local newPos = Vector3.new(currentPos.X, newY, currentPos.Z)
character:PivotTo(CFrame.new(newPos))
task.wait(0.03)
end
character:PivotTo(CFrame.new(currentPos.X, targetY, currentPos.Z))
return true
end
local function smoothDirectMove(character, startPos, endPos, speed)
local distance = (endPos - startPos).Magnitude
local travelTime = distance / speed
local startTime = tick()
while tick() - startTime < travelTime do
if not isMoving then
return false
end
local alpha = (tick() - startTime) / travelTime
local interpPos = startPos:Lerp(endPos, alpha)
character:PivotTo(CFrame.new(interpPos))
task.wait(0.03)
end
character:PivotTo(CFrame.new(endPos))
isMoving = false
return true
end
local function startDirectMove()
local character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
local plotsFolder = game.Workspace:FindFirstChild("GameAssets")
if not plotsFolder then return end
local plots = plotsFolder:FindFirstChild("Plots")
if not plots then return end
local plotChildren = plots:GetChildren()
for i = 1, #plotChildren do
local v = plotChildren[i]
if v:IsA("Folder") and v:FindFirstChild("Avatar") and v.Avatar:FindFirstChild("Info") and v.Avatar.Info:FindFirstChild("ImageLabel") and v.Avatar.Info.ImageLabel.Image:find(LocalPlayer.UserId) then
local lockObj = v:FindFirstChild("Lock")
if not lockObj or not lockObj:FindFirstChild("Color") then continue end
local targetPart = lockObj:FindFirstChild("Color")
local targetPos = targetPart.Position
local currentCFrame = character:GetPivot()
local startPos = currentCFrame.Position
print("TargetPart:", targetPart, "CanCollide:", targetPart.CanCollide)
-- Step 1: Slowly ascend (only once, from ground to elevated Y)
local ascended = smoothVerticalMove(character, startPos.Y, startPos.Y + yOffset, verticalMoveSpeed)
if not ascended then return end
-- Step 2: Direct movement at elevated Y
local elevatedStartPos = Vector3.new(startPos.X, startPos.Y + yOffset, startPos.Z)
local elevatedTargetPos = Vector3.new(targetPos.X, targetPos.Y + yOffset, targetPos.Z)
print("Moving directly to target position at elevated Y.")
local directMoved = smoothDirectMove(character, elevatedStartPos, elevatedTargetPos, moveSpeed)
if not directMoved then return end
-- Step 3: Slowly descend (only once, from elevated Y to ground Y)
local finalPos = character:GetPivot().Position
smoothVerticalMove(character, finalPos.Y, finalPos.Y - yOffset, verticalMoveSpeed)
end
end
end
local function toggleMove()
if isMoving then
isMoving = false
else
isMoving = true
moveCoroutine = coroutine.create(startDirectMove)
coroutine.resume(moveCoroutine)
end
end
UserInputService.InputBegan:Connect(function(input, gameProcessed)
if gameProcessed then return end
if input.KeyCode == Enum.KeyCode.Q then
toggleMove()
end
end)
for mobile if they use keyboard script
@RealEric yeah if you have a keyboard you can use it.