
Key Required

--!strict
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local player = Players.LocalPlayer
-- =========================
-- CONFIG
-- =========================
local CONFIG = {
TargetSpeed = 250, -- ความเร็วหลักแกน Z
RoadName = "AutoFarmRoad",
RoadSize = Vector3.new(200, 10, 900000),
RoadPosition = Vector3.new(0, 10000, 0),
SpawnPosition = Vector3.new(0, 10015, 0),
SpawnYaw = 0, -- องศาที่หันตอนวางรถกลับ
MinYBeforeReset = 9500,
MaxZBeforeReset = 400000,
CenterX = 0, -- กลางถนน
CenteringGain = 4.5, -- แรงดึงกลับแกน X
MaxSideVelocity = 120, -- จำกัดความเร็วด้านข้าง ไม่ให้ดีดแรงเกิน
TeleportCooldown = 0.25,
OrientationResponsiveness = 50, -- ค่ายิ่งมากยิ่งหันไว
OrientationMaxTorque = 1e9,
}
-- =========================
-- STATE
-- =========================
local currentVehicle: Model? = nil
local currentMainPart: BasePart? = nil
local isResetting = false
local heartbeatConnection: RBXScriptConnection? = nil
-- =========================
-- ROAD SETUP
-- =========================
local function ensureRoad(): Part
local road = workspace:FindFirstChild(CONFIG.RoadName)
if road and road:IsA("Part") then
road.Size = CONFIG.RoadSize
road.Position = CONFIG.RoadPosition
return road
end
if road and not road:IsA("Part") then
road:Destroy()
end
local newRoad = Instance.new("Part")
newRoad.Name = CONFIG.RoadName
newRoad.Size = CONFIG.RoadSize
newRoad.Position = CONFIG.RoadPosition
newRoad.Anchored = true
newRoad.CanCollide = true
newRoad.CanTouch = false
newRoad.CanQuery = false
newRoad.Transparency = 0.5
newRoad.Material = Enum.Material.SmoothPlastic
newRoad.CastShadow = false
newRoad.Locked = true
newRoad.Parent = workspace
return newRoad
end
ensureRoad()
-- =========================
-- UTILS
-- =========================
local function getCharacter(): Model?
return player.Character
end
local function getHumanoid(character: Model?): Humanoid?
if not character then
return nil
end
return character:FindFirstChildOfClass("Humanoid")
end
local function getSeatedVehicle(): (Model?, BasePart?)
local character = getCharacter()
local humanoid = getHumanoid(character)
if not character or not humanoid then
return nil, nil
end
local seat = humanoid.SeatPart
if not seat or not seat:IsA("BasePart") then
return nil, nil
end
local vehicle = seat:FindFirstAncestorOfClass("Model")
if not vehicle then
return nil, nil
end
local mainPart = vehicle.PrimaryPart or seat
if not mainPart or not mainPart:IsA("BasePart") then
return nil, nil
end
return vehicle, mainPart
end
local function clearControllerObjects(part: BasePart?)
if not part then
return
end
local oldAttachment = part:FindFirstChild("AF_Attachment")
if oldAttachment then
oldAttachment:Destroy()
end
local oldAlign = part:FindFirstChild("AF_AlignOrientation")
if oldAlign then
oldAlign:Destroy()
end
end
local function setupOrientationController(part: BasePart)
clearControllerObjects(part)
local attachment = Instance.new("Attachment")
attachment.Name = "AF_Attachment"
attachment.Parent = part
local align = Instance.new("AlignOrientation")
align.Name = "AF_AlignOrientation"
align.Mode = Enum.OrientationAlignmentMode.OneAttachment
align.Attachment0 = attachment
align.RigidityEnabled = false
align.ReactionTorqueEnabled = false
align.Responsiveness = CONFIG.OrientationResponsiveness
align.MaxTorque = CONFIG.OrientationMaxTorque
align.CFrame = CFrame.lookAt(Vector3.zero, Vector3.new(0, 0, 1), Vector3.new(0, 1, 0))
align.Parent = part
end
local function bindVehicle(vehicle: Model, mainPart: BasePart)
if currentMainPart == mainPart and currentVehicle == vehicle then
return
end
if currentMainPart then
clearControllerObjects(currentMainPart)
end
currentVehicle = vehicle
currentMainPart = mainPart
setupOrientationController(mainPart)
end
local function unbindVehicle()
if currentMainPart then
clearControllerObjects(currentMainPart)
end
currentVehicle = nil
currentMainPart = nil
end
local function resetVehicle(vehicle: Model?, mainPart: BasePart?)
if isResetting or not mainPart then
return
end
isResetting = true
mainPart.AssemblyLinearVelocity = Vector3.zero
mainPart.AssemblyAngularVelocity = Vector3.zero
local spawnCF = CFrame.new(CONFIG.SpawnPosition) * CFrame.Angles(0, math.rad(CONFIG.SpawnYaw), 0)
if vehicle then
vehicle:PivotTo(spawnCF)
else
mainPart.CFrame = spawnCF
end
task.delay(CONFIG.TeleportCooldown, function()
isResetting = false
end)
end
-- =========================
-- MAIN LOOP
-- =========================
local function stepVehicle()
if isResetting then
return
end
local vehicle, mainPart = getSeatedVehicle()
if not vehicle or not mainPart then
unbindVehicle()
return
end
bindVehicle(vehicle, mainPart)
local pos = mainPart.Position
-- รีเซ็ตกลับต้นทางถ้าหลุดจากพื้นที่ที่กำหนด
if pos.Y < CONFIG.MinYBeforeReset or pos.Z > CONFIG.MaxZBeforeReset then
resetVehicle(vehicle, mainPart)
return
end
-- ล็อกอัตราหมุนไม่ให้รถเหวี่ยง/ล้มง่าย
mainPart.AssemblyAngularVelocity = Vector3.zero
-- ดึงกลับสู่แกนกลางถนน
local lateralError = CONFIG.CenterX - pos.X
local sideVelocity = math.clamp(
lateralError * CONFIG.CenteringGain,
-CONFIG.MaxSideVelocity,
CONFIG.MaxSideVelocity
)
-- คง Y velocity เดิมไว้ เพื่อไม่ฝืนแรงโน้มถ่วงจนผิดธรรมชาติ
local currentYVelocity = mainPart.AssemblyLinearVelocity.Y
mainPart.AssemblyLinearVelocity = Vector3.new(
sideVelocity,
currentYVelocity,
CONFIG.TargetSpeed
)
end
-- กันรันซ้ำแล้วมีหลาย connection
if _G.AutoDriveConnection then
_G.AutoDriveConnection:Disconnect()
_G.AutoDriveConnection = nil
end
heartbeatConnection = RunService.Heartbeat:Connect(stepVehicle)
_G.AutoDriveConnection = heartbeatConnection
-- cleanup ตอนตัวละครเปลี่ยน
player.CharacterRemoving:Connect(function()
unbindVehicle()
end)
its slow
@czo0 Join the group for maps and earn extra money