Effective Way to Approach Car AI

I am currently making a car AI that travels on a static path across a city. It uses PathfindingService and is based on points.

These are the barriers. I am using PathfindingModifers.


(ignore the text.)

Here are the points (highlighted because it is hard to see):


The car moves in the direction of the arrow.

Here are my barriers for that path:

Here is a snippet of my code:

function module:Pathfind()
	if (self.Running == true) then warn("Already pathfinding for AI " .. self.AI.Name .. ".") return end
	
	local tries = 0
	
	local paths
	repeat paths = module.getPathsFromTagName(self.TagName) tries += 1 task.wait(0.05) until (paths ~= nil or tries >= 10)
	
	local chosenPath = paths[math.random(1, #paths)]
	chosenPath:SetAttribute("AITaken", true)
	
	self.AgentParameters.Costs[chosenPath.Name] = math.huge
	self.Path = pfs:CreatePath(self.AgentParameters)

	self.AI:PivotTo(chosenPath.SpawnPoint:GetPivot())
	
	task.spawn(function()
		while (true) do
			if (self.Destroy == true) then
				self.Path:Destroy()
				self.AI = nil
				self.TagName = nil
				self.PathfindingCallback = nil
				self.AI = nil
				
				break
			end

			for index = 1, #chosenPath.Points:GetChildren(), 1 do
				self:Update(chosenPath.Points["Point" .. index])
			end
			
			self:Update(chosenPath.SpawnPoint)
			self.PathfindingFinished:Fire()
			task.wait(3)
		end
	end)
end

The actual worker:

local function getRestrainedLookAt(cf)
	local _, _, y = cf:ToOrientation()
	return cf * CFrame.Angles(0, y, 0)
end

function module.run(plot, _, xp)
	local car = script.Cars:GetChildren()[math.random(1, #script.Cars:GetChildren())]:Clone()
	car.Parent = plot.Island.AIs

	local carCf = Instance.new("CFrameValue", car)
	carCf.Value = car:GetPivot()

	carCf.Changed:Connect(function(val)
		car:PivotTo(val)
	end)
	
	local path = pfm.new(car, "DriverPaths" .. plot.Name, {AgentRadius = 5, AgentHeight = 2})
	
	path:SetPathfindingCallback(function(cf)
		local tween = game:GetService("TweenService"):Create(carCf, TweenInfo.new(0.1), {Value = getRestrainedLookAt(cf)})

		tween:Play()
		tween.Completed:Wait()
	end)
	
	path.PathfindingFinished:Connect(function()
		xp(50)
	end)
	
	path:Pathfind()
end

return module

The problem that I am having is that the car is inconsistent. It pathfinds fine on the straight line, but I am not sure how I will get it to work 100% of the time on turns.

There also may be a better way to approach this, in which I would like to hear suggestions.

Heres a video of it:

Thanks.

I personally use the SimplePath module for my AI. If you want to give it a look, you can find it here it can be used for multiple things including your Car AI, but it might be a little more complicated if the car doesn’t have a humanoid.

Would that help solve the problem with the curves? I can add a humanoid to the car in the worst case scenario.

Could you also explain how it approaches pathfinding differently than the normal PathfindingService?

Yeah, you could add waypoints for each curve and it does it quite smoothly.

1 Like

I’m just curious, does the car have any use to the player? I can imagine this being a taxi and players could select the point they want to travel to, basically a fancier type of teleport feature.

No, it does not.

@Redanite I am currently trying your solution and I will let you know.

It did not work. I tried it with a character and a car to be sure.

That’s strange, could you send the code?