Make "AI" car countersteer when going off the racing line

Ok so, i have a script which makes a car follow a specified racing line around the track, it works great but the problem is that it starts going side to side from the line, eventually just crashing.

i already tried doing a “buffer zone” which somewhat works at slow speeds (for some time), but when the car picks up more speed it becomes useless and the side to side problem rises yet again

External Media

im trying to see if theres a possible and effective way to make the car countersteer when turning into the line

while true do
	task.wait()
	local closestPoint = nil
	local minDistance = math.huge
	local carPosition = LineFollower.Position

	for _, linePoint in pairs(Lines:GetChildren()) do
		local distance = (linePoint.Position - carPosition).magnitude
		if distance < minDistance then
			minDistance = distance
			closestPoint = linePoint
		end
	end

	if closestPoint then
		local difference = closestPoint.CFrame:PointToObjectSpace(LineFollower.CFrame.Position)
		local steer = difference.X

		if steer ~= nil then
			seat.Throttle = 1

			-- define buffer zone boundaries
			local leftBoundary = -bufferZone
			local rightBoundary = bufferZone

			-- check if car is inside buffer zone
			if difference.X > rightBoundary then
				-- turn left
				seat.SteerFloat = -1
				seat.TurnSpeed = origturn
			elseif difference.X > -rightBoundary then
				seat.SteerFloat = -0.5
				seat.TurnSpeed = .1
				
			elseif difference.X < leftBoundary then
				-- turn right
				seat.SteerFloat = 1
				seat.TurnSpeed = origturn
			elseif difference.X < -leftBoundary then
				seat.SteerFloat = 0.5
				seat.TurnSpeed = .1
			else
				-- straighten the car
				seat.SteerFloat = 0
				seat.TurnSpeed = origturn
			end
		else
			seat.Throttle = 0
			seat.Steer = 0
		end
	end
end

heres the script that i use

1 Like

This isn’t the right way to go. Vector3:Dot is what you need:

function seatMove(humanoid, dir, root)
	humanoid.SeatPart.ThrottleFloat = dir:Dot(root.CFrame.LookVector)
	humanoid.SeatPart.SteerFloat = dir.Unit:Dot(root.CFrame.RightVector) * humanoid.SeatPart.ThrottleFloat * 2 -- sensitivity
end
--dir is the direction, specify like this:
local dir = targetPosition - root.Position
--root is the HumanoidRootPart of the humanoid (you could use the car seat as well)

I believe your system could work with enough effort, but it would need a dead zone (buffer zone) that is more defined and accurate, which is simply not possible at lower framerates.

I’ve also realized that Roblox’s legacy car system does not respect the floating-point value of SteerFloat and ThrottleFloat, and instead converts them to integers. I’ve switched a handful of my cars to LegacyCarConverter and they work much better:

The reason why it works much better is because you can customize the steering angle with the script AND with SteerFloat. Though that is just my experience.

1 Like