To start this off, I didn’t make this script, this is altering a scripted system that a friend made and he is no longer around (left the platform and deleted all social channels) to assist me in altering his creation.
So here is the issue, when you activate the cruise control, the script adjusts the torque, throttle, and more to allow for a constant state of speed. However in doing this, below a certain threshold speed (dependent on your gear ratios and max speed setting) the script doesn’t adjust parameters correctly enough to maintain speed. Rather it has no power and the vehicle stops.
If the player presses the accelerator during this it will accelerate to the speed set when you activate cruise but you have to hold the throttle to maintain speed. It should be the other way around.
I believe I know where this happens, it is the line that goes as follows:
local engineChange = cruiseControl.Value and 0.0 or (thr * tq * gmul) + engineDrag + engineFeedback
A breakdown is this: engineChange is a setting applied to the vehicle in motion, if the Cruise Control value is true, it adjusts that setting to 0 which cuts the acceleration or something to 0 and thus the vehicle cannot accelerate nor decelerate. At least this is what is supposed to be the case. I am genuinely at witts end trying to figure out why its behaving so oddly below a certain speed.
Here is the full script:
--------------------------------------------------------------------------------------------------
local coast = 0.01 -- Affects coasting.
--local brakeMultiplier = 2 -- Affects braking power.
--------------------------------------------------------------------------------------------------
-- Changing anything below is likely going to break the car, only advanced scripters should continue.
local UIS = game:GetService("UserInputService")
local shoulderDeadzone = 0.05
local stickDeadzone = 0.25
local P = script.Parent
local player = game.Players.LocalPlayer
wait(0.2)
local CarObject = script.CarObject.Value
local seat = CarObject.VehicleSeat
local exhausts = CarObject.Exhausts
local vars = seat.ATSVariables
local fuelVars = seat.FuelVariables
local powerwheels = {}
local steerMotors = {}
for i,v in pairs(CarObject.Wheels:GetChildren()) do
if (v.Wheel:FindFirstChild("BAV")) and (v.Wheel.BAV.P > 0) then
table.insert(powerwheels, v.Wheel)
end
if (v:FindFirstChild("Steer")) then
table.insert(steerMotors, v.Steer.Motor)
end
end
local wheelRadius = powerwheels[1].Size.x / 2
local automatic = vars.AutomaticMode
local redlineTimer = 0.0
local engineRPM = vars.RPM
local wheelRPM = 0.0
local gearRatios = {-0.3, 0.0, 1.0}
local currentGear = vars.Gear
local smoothThrottle = vars.SmoothThrottle
local cruiseControl = vars.CruiseControl
local clutch = vars.Clutch
local steeringAngle = vars.SteeringAngle
local steeringSpeed = vars.SteeringSpeed
local maxSpeed = vars.MaxSpeed
local brakePower = vars.BrakePower
local afmTrsh = fuelVars.AFMTrsh
local fuel = fuelVars.Fuel
local fuelDriveDrain = fuelVars.FuelDriveDrain
local fuelIdleDrain = fuelVars.FuelIdleDrain
local instconsum = fuelVars.Instconsum
local speed = fuelVars.Speed
local fuelSysActivator = fuelVars.FuelSystemActivator
-------------------------------------------------------------------------------------------------
-- DisableDetectorFunctions and varables
function Stop()
for i,v in pairs(CarObject.Wheels:GetChildren()) do
if (v:FindFirstChild("BAV")) then
v.BAV.angularvelocity = Vector3.new()
end
end
vars.Gear.Value = 0
vars.RPM.Value = 0
vars.SmoothThrottle.Value = 0
SetExhaustsEnabled(false)
end
seat.ChildRemoved:connect(function(child)
if (child.Name == "SeatWeld") then
Stop()
--script:Destroy()
end
end)
P.Changed:connect(function(property)
if (property == "Disabled") and (P.Disabled == true) then
Stop()
end
end)
--------------------------------------------------------------------------------------------------
-- Methods
function SetExhaustsEnabled(bool)
for i,v in ipairs(exhausts:GetChildren()) do
if v.Name=="Emitter" then
v.SmokeFumes.Enabled = bool
end
end
end
function Clamp(val, Min, Max) return math.min( math.max(val, Min), Max) end
function GetInput()
local inputs = {0.0, 0.0, 0.0} -- Forward, Brake, Steering
if (UIS:GetGamepadConnected(Enum.UserInputType.Gamepad1)) then
local GP1state = UIS:GetGamepadState(Enum.UserInputType.Gamepad1)
for i,v in pairs(GP1state) do
if (v.KeyCode == Enum.KeyCode.ButtonR2) then
if (currentGear.Value >= 0) then
inputs[1] = (v.Position.z > shoulderDeadzone) and v.Position.z or 0.0
else
inputs[2] = (v.Position.z > shoulderDeadzone) and v.Position.z or 0.0
end
elseif (v.KeyCode == Enum.KeyCode.ButtonL2) then
if (currentGear.Value >= 0) then
inputs[2] = (v.Position.z > shoulderDeadzone) and v.Position.z or 0.0
else
inputs[1] = (v.Position.z > shoulderDeadzone) and v.Position.z or 0.0
end
elseif (v.KeyCode == Enum.KeyCode.Thumbstick1) then
inputs[3] = (math.abs(v.Position.x) > stickDeadzone) and v.Position.x or 0.0
end
end
end
local wKey = (UIS:IsKeyDown(Enum.KeyCode.W) or UIS:IsKeyDown(Enum.KeyCode.Up)) and 1 or 0
local sKey = (UIS:IsKeyDown(Enum.KeyCode.S) or UIS:IsKeyDown(Enum.KeyCode.Down)) and 1 or 0
local aKey = (UIS:IsKeyDown(Enum.KeyCode.A) or UIS:IsKeyDown(Enum.KeyCode.Left)) and 1 or 0
local dKey = (UIS:IsKeyDown(Enum.KeyCode.D) or UIS:IsKeyDown(Enum.KeyCode.Right)) and 1 or 0
if (currentGear.Value >= 0) then
inputs[1] = math.max(wKey, inputs[1])
inputs[2] = math.max(sKey, inputs[2])
else
inputs[1] = math.max(sKey, inputs[1])
inputs[2] = math.max(wKey, inputs[2])
end
local keySteer = dKey - aKey
if (math.abs(keySteer) > math.abs(inputs[3])) then
inputs[3] = keySteer
end
return inputs
end
function SetThrottle(newThrottle)
newThrottle = newThrottle / wheelRadius -- Fix
for i,v in pairs(powerwheels) do
local dir = seat.CFrame.lookVector
if (v.Parent:FindFirstChild("Steer")) then
dir = (v.Parent.Steer.CFrame * CFrame.Angles(math.pi/2, 0, 0)).lookVector
end
v.BAV.angularvelocity = dir * newThrottle
end
end
function SetGear(gear) currentGear.Value = Clamp(gear, -1, 1) end
function GetGearRatio() return gearRatios[currentGear.Value+2] end
function ToEngineRPM(_wheelRPM) return (gearRatios[currentGear.Value+2] == 0) and 0 or _wheelRPM / gearRatios[currentGear.Value+2] end
function ToWheelRPM(_engineRPM) return _engineRPM * gearRatios[currentGear.Value+2] end
function GetWheelSpeed()
local wspd = 0.0
for i,v in pairs(powerwheels) do
local v = powerwheels[i]
if (v.RotVelocity.magnitude > 0.0) then
local side = (v.CFrame * CFrame.Angles(math.pi / 1.8, 0, 0)).lookVector.unit
local rVel = (v.RotVelocity:Dot(side) * v.RotVelocity.unit).magnitude
wspd = wspd + rVel
end
end
wspd = wspd / #powerwheels * wheelRadius
vars.WheelSpeed.Value = wspd
return wspd
end
exhausts_debounce = false
function SetExhausts(transparency)
coroutine.resume(coroutine.create(function()
if exhausts_debounce then return end
exhausts_debounce = true
for i,v in ipairs(exhausts:GetChildren()) do
if v.Name=="Emitter" then
v.SmokeFumes.Transparency = NumberSequence.new{
NumberSequenceKeypoint.new(0,transparency,0),
NumberSequenceKeypoint.new(1,1,0)
}
end
end
wait(3)
exhausts_debounce = false
end))
end
function Main(deltaTime)
-- Prerequisites
redlineTimer = redlineTimer - deltaTime
local inputs = GetInput()
if fuel.Value<=0 then
inputs[1] = 0
inputs[2] = 0
fuel.Value = 0
Stop()
end
fuel.Value = (fuelSysActivator.Value and (inputs[1]==1 or inputs[2]==1)) and fuel.Value - fuelDriveDrain.Value or fuel.Value
fuel.Value = (fuelSysActivator.Value and (inputs[1]==0 and inputs[2]==0)) and fuel.Value - fuelIdleDrain.Value or fuel.Value
local brk = inputs[2] * brakePower.Value --brakeMultiplier
vars.TrueBrake.Value = brk
local thr = (redlineTimer <= 0) and inputs[1] * math.max(clutch.Value, 0.1) or 0.0
smoothThrottle.Value = 0.8 * smoothThrottle.Value + 0.2 * thr
local trueSpeed = seat.Velocity.magnitude
local wheelSpeed = GetWheelSpeed()
clutch.Value = math.min(clutch.Value + deltaTime * 2, 1.0)
local connection = (currentGear.Value == 0) and 0.0 or clutch.Value
-- Steering
local steerInfluence = 1 - math.min(trueSpeed / 300, 0.5)
--print(trueSpeed,trueSpeed / 300)
for i,v in pairs(steerMotors) do
v.DesiredAngle = (inputs[3] * steeringSpeed.Value * (steerInfluence))*steeringAngle.Value
end
-- Redline
if (engineRPM.Value >= 1.0) then redlineTimer = 0.05 end
-- Gearing
if (automatic.Value) and (currentGear.Value == 0) and (brk > 0.0) then
SetGear(-1)
local t = brk
--brk = throttle
thr = t
end
if (automatic.Value) and (currentGear.Value == 0) and (thr > 0.1) then SetGear(1) end
if (automatic.Value) and (thr < 0.01) and (engineRPM.Value < 0.35) and (currentGear.Value == 1 or currentGear.Value == -1) then SetGear(0) end
if (automatic.Value) then
if (engineRPM.Value > 0.8 and currentGear.Value > 0 and currentGear.Value < 6) then
SetGear(currentGear.Value + 1)
elseif (engineRPM.Value < 0.35 and currentGear.Value > 1) then
SetGear(currentGear.Value - 1)
end
end
-- Drivetrain
local engineFeedback = (currentGear.Value ~= 0) and (wheelSpeed - math.abs(ToWheelRPM(engineRPM.Value) * maxSpeed.Value)) * 0.05 or 0.0
local engineDrag = (currentGear.Value == 0) and (thr < 0.5) and -0.5 or 0.0
local tq = ((engineRPM.Value^2-(engineRPM.Value-0.05)^3) * 1.35 + 0.7) * seat.Torque * 0.01
local gmul = (currentGear.Value ~= 0) and math.abs(1/GetGearRatio()) or 7
local engineChange = cruiseControl.Value and 0.0 or (thr * tq * gmul) + engineDrag + engineFeedback
print(engineChange)
engineRPM.Value = Clamp(engineRPM.Value + engineChange * deltaTime, 0.1, 1.0)
-- External forces / braking
local finalDrag = (currentGear.Value == 0) and 0.0 or Clamp(currentGear.Value, -1, 1) * -coast * math.abs(1/GetGearRatio())
local finalBrake = 1 - brk
wheelRPM = ((currentGear.Value == 0) and wheelRPM * 0.01 or finalBrake * ((1-connection) * wheelRPM + connection * ToWheelRPM(engineRPM.Value) + (finalDrag) * deltaTime))
local finalExhausts = finalBrake<0 and 0.925 or 0.975
SetThrottle(wheelRPM * maxSpeed.Value)
SetExhausts(finalExhausts)
end
currentGear.Changed:connect(function() clutch.Value = 0.0 end)
-- Main loop
local success, message
while true do
success, message = pcall(Main, wait())
if (not success) then break end
if engineRPM.Value ~= 0 then
seat.Engine:FireServer("Rev",engineRPM.Value)
end
if smoothThrottle.Value ~= 0 then
seat.Trot:FireServer(smoothThrottle.Value)
end
end
print("ATS error: "..message)