Hey! I’m happy to see this question, since I actually built the car with these sorts of use-cases in mind.
You can start out by removing some of the unnecessary client control scripts and adding a new script for the AI driving
To make the car drive around, all you need to do is hook up the Controller:update
function
-- AI driver script
local RunService = game:GetService("RunService")
local Controller = require(script.Parent.Parent.Controller)
local function onStepped(_, deltaTime: number)
Controller:update(deltaTime)
end
RunService.Stepped:Connect(onStepped)
You can now change the steeringInput
, throttleInput
, nitroInput
, and handBrakeInput
attributes on Car.Inputs
and it will respond accordingly.
Making a proper car driving algorithm is a lot more involved, as you’ll want to do some sort of path planning to optimize the steering/throttle/braking/etc, but here’s a simple example of getting it to drive to a specific target part in workspace.
-- AI driver script
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
local Controller = require(script.Parent.Parent.Controller)
local Constants = require(script.Parent.Parent.Constants)
local car = script.Parent.Parent.Parent
local chassis = car.Chassis
local inputs = car.Inputs
local target = Workspace.Target
local MIN_SPEED_DISTANCE = 20
local MAX_SPEED_DISTANCE = 100
local function onStepped(_, deltaTime: number)
-- Calculate the direction to the target
local targetOffset = chassis.CFrame:PointToObjectSpace(target.Position)
local targetAngle = math.atan2(targetOffset.X, -targetOffset.Z)
-- Update the steering direction
inputs:SetAttribute(Constants.STEERING_INPUT_ATTRIBUTE, targetAngle)
-- Calculate the distance to the target
local distance = targetOffset.Magnitude
-- Calculate a throttle speed based on distance. We want to go slower when closer so
-- that our turning radius is tighter
local throttle = math.clamp((distance - MIN_SPEED_DISTANCE) / MAX_SPEED_DISTANCE, 0, 1)
-- Update the throttle
inputs:SetAttribute(Constants.THROTTLE_INPUT_ATTRIBUTE, throttle)
-- Update the controller
Controller:update(deltaTime)
end
RunService.Stepped:Connect(onStepped)
You could modify this to pick the next target in your path once the car gets close enough