Creating Custom Vehicle Scripts in FiveM

Master vehicle scripting in FiveM with this comprehensive guide covering spawning systems, customization, and advanced vehicle management features.

📅 January 5, 2024⏱️ 18 min read🏷️ Vehicle Scripts

Vehicle scripts are essential for creating immersive FiveM experiences. From simple spawn systems to complex vehicle management, this guide covers everything you need to create professional vehicle scripts.

1. Basic Vehicle Spawning

-- Basic vehicle spawning
RegisterCommand('spawncar', function(source, args)
    local playerPed = PlayerPedId()
    local playerCoords = GetEntityCoords(playerPed)
    local playerHeading = GetEntityHeading(playerPed)
    
    -- Spawn vehicle in front of player
    local spawnCoords = GetOffsetFromEntityInWorldCoords(playerPed, 0.0, 5.0, 0.0)
    
    local vehicleHash = GetHashKey(args[1] or 'adder')
    RequestModel(vehicleHash)
    
    while not HasModelLoaded(vehicleHash) do
        Citizen.Wait(0)
    end
    
    local vehicle = CreateVehicle(vehicleHash, spawnCoords.x, spawnCoords.y, spawnCoords.z, playerHeading, true, false)
    SetPedIntoVehicle(playerPed, vehicle, -1)
    
    -- Clean up
    SetModelAsNoLongerNeeded(vehicleHash)
end, false)

2. Advanced Spawn System

-- Advanced vehicle spawn system
local VehicleSpawner = {}

-- Vehicle categories
VehicleSpawner.Categories = {
    sports = {'adder', 'zentorno', 't20', 'osiris'},
    super = {'voltic', 'cheetah', 'entityxf', 'infernus'},
    motorcycles = {'bati', 'hakuchou', 'akuma', 'carbonrs'},
    offroad = {'sandking', 'brawler', 'rebel', 'dune'}
}

function VehicleSpawner.SpawnVehicle(vehicleModel, coords, heading)
    local vehicleHash = GetHashKey(vehicleModel)
    
    -- Request model
    RequestModel(vehicleHash)
    local timeout = 0
    while not HasModelLoaded(vehicleHash) and timeout < 5000 do
        Citizen.Wait(100)
        timeout = timeout + 100
    end
    
    if not HasModelLoaded(vehicleHash) then
        print("Failed to load vehicle model: " .. vehicleModel)
        return nil
    end
    
    -- Create vehicle
    local vehicle = CreateVehicle(vehicleHash, coords.x, coords.y, coords.z, heading, true, false)
    
    -- Configure vehicle
    SetVehicleOnGroundProperly(vehicle)
    SetVehicleHasBeenOwnedByPlayer(vehicle, true)
    SetEntityAsMissionEntity(vehicle, true, true)
    
    -- Clean up
    SetModelAsNoLongerNeeded(vehicleHash)
    
    return vehicle
end

-- Usage
RegisterCommand('spawn', function(source, args)
    local category = args[1] or 'sports'
    local vehicles = VehicleSpawner.Categories[category]
    
    if vehicles then
        local randomVehicle = vehicles[math.random(#vehicles)]
        local playerPed = PlayerPedId()
        local coords = GetEntityCoords(playerPed)
        local heading = GetEntityHeading(playerPed)
        
        local vehicle = VehicleSpawner.SpawnVehicle(randomVehicle, coords, heading)
        if vehicle then
            SetPedIntoVehicle(playerPed, vehicle, -1)
        end
    end
end, false)

3. Vehicle Management

-- Vehicle management system
local VehicleManager = {}

-- Track spawned vehicles
VehicleManager.SpawnedVehicles = {}

function VehicleManager.RegisterVehicle(vehicle)
    local vehicleId = GetVehicleNumberPlateText(vehicle)
    VehicleManager.SpawnedVehicles[vehicleId] = {
        entity = vehicle,
        owner = GetPlayerServerId(PlayerId()),
        spawnTime = GetGameTimer(),
        coords = GetEntityCoords(vehicle)
    }
end

function VehicleManager.CleanupOldVehicles()
    local currentTime = GetGameTimer()
    local maxAge = 1800000 -- 30 minutes
    
    for plate, data in pairs(VehicleManager.SpawnedVehicles) do
        if currentTime - data.spawnTime > maxAge then
            if DoesEntityExist(data.entity) then
                DeleteEntity(data.entity)
            end
            VehicleManager.SpawnedVehicles[plate] = nil
        end
    end
end

-- Cleanup thread
Citizen.CreateThread(function()
    while true do
        Citizen.Wait(300000) -- Check every 5 minutes
        VehicleManager.CleanupOldVehicles()
    end
end)

-- Track vehicle deletion
AddEventHandler('entityRemoved', function(entity)
    if GetEntityType(entity) == 2 then -- Vehicle
        local plate = GetVehicleNumberPlateText(entity)
        if VehicleManager.SpawnedVehicles[plate] then
            VehicleManager.SpawnedVehicles[plate] = nil
        end
    end
end)

4. Vehicle Customization

-- Vehicle customization system
local VehicleCustomizer = {}

function VehicleCustomizer.ApplyCustomization(vehicle, customization)
    -- Paint job
    if customization.color then
        SetVehicleColours(vehicle, customization.color.primary, customization.color.secondary)
    end
    
    -- Wheels
    if customization.wheels then
        SetVehicleWheelType(vehicle, customization.wheels.type)
        SetVehicleMod(vehicle, 23, customization.wheels.mod, false)
    end
    
    -- Performance mods
    if customization.performance then
        SetVehicleMod(vehicle, 11, customization.performance.engine, false) -- Engine
        SetVehicleMod(vehicle, 12, customization.performance.brakes, false) -- Brakes
        SetVehicleMod(vehicle, 13, customization.performance.transmission, false) -- Transmission
        SetVehicleMod(vehicle, 15, customization.performance.suspension, false) -- Suspension
    end
    
    -- Visual mods
    if customization.visual then
        for modType, modIndex in pairs(customization.visual) do
            SetVehicleMod(vehicle, tonumber(modType), modIndex, false)
        end
    end
    
    -- Turbo
    if customization.turbo then
        ToggleVehicleMod(vehicle, 18, customization.turbo) -- Turbo
    end
    
    -- Neon
    if customization.neon then
        SetVehicleNeonLightEnabled(vehicle, 0, customization.neon.front)
        SetVehicleNeonLightEnabled(vehicle, 1, customization.neon.back)
        SetVehicleNeonLightEnabled(vehicle, 2, customization.neon.left)
        SetVehicleNeonLightEnabled(vehicle, 3, customization.neon.right)
        
        if customization.neon.color then
            SetVehicleNeonLightsColour(vehicle, customization.neon.color.r, customization.neon.color.g, customization.neon.color.b)
        end
    end
end

-- Example customization
local customConfig = {
    color = { primary = 0, secondary = 0 }, -- Black
    wheels = { type = 0, mod = 2 },
    performance = { engine = 3, brakes = 2, transmission = 2, suspension = 1 },
    visual = { [0] = 1, [1] = 1, [2] = 1 }, -- Mod indices
    turbo = true,
    neon = {
        front = true, back = true, left = true, right = true,
        color = { r = 0, g = 255, b = 255 } -- Cyan
    }
}

RegisterCommand('customize', function()
    local vehicle = GetVehiclePedIsIn(PlayerPedId(), false)
    if vehicle ~= 0 then
        VehicleCustomizer.ApplyCustomization(vehicle, customConfig)
    end
end, false)

5. Advanced Features

Vehicle Lock System

-- Vehicle lock system
local VehicleLocks = {}

function VehicleLocks.ToggleLock(vehicle)
    local plate = GetVehicleNumberPlateText(vehicle)
    local playerId = GetPlayerServerId(PlayerId())
    
    -- Check if player owns this vehicle
    if VehicleLocks.IsOwner(plate, playerId) then
        local isLocked = GetVehicleDoorsLockedForPlayer(vehicle, PlayerId())
        
        if isLocked then
            SetVehicleDoorsLockedForPlayer(vehicle, PlayerId(), false)
            ShowNotification("Vehicle unlocked")
        else
            SetVehicleDoorsLockedForPlayer(vehicle, PlayerId(), true)
            ShowNotification("Vehicle locked")
        end
    else
        ShowNotification("You don't own this vehicle")
    end
end

function VehicleLocks.IsOwner(plate, playerId)
    -- Check ownership in database or local storage
    return true -- Simplified for example
end

-- Key bind for locking
RegisterKeyMapping('lockvehicle', 'Toggle Vehicle Lock', 'keyboard', 'L')

RegisterCommand('lockvehicle', function()
    local vehicle = GetVehiclePedIsIn(PlayerPedId(), false)
    if vehicle ~= 0 then
        VehicleLocks.ToggleLock(vehicle)
    end
end, false)

Vehicle Tracking

-- Vehicle tracking system
local VehicleTracker = {}

function VehicleTracker.StartTracking(vehicle)
    local plate = GetVehicleNumberPlateText(vehicle)
    
    Citizen.CreateThread(function()
        while DoesEntityExist(vehicle) do
            local coords = GetEntityCoords(vehicle)
            local heading = GetEntityHeading(vehicle)
            
            -- Send position to server
            TriggerServerEvent('vehicleTracker:updatePosition', plate, coords, heading)
            
            Citizen.Wait(5000) -- Update every 5 seconds
        end
    end)
end

-- Server-side tracking
RegisterNetEvent('vehicleTracker:updatePosition')
AddEventHandler('vehicleTracker:updatePosition', function(plate, coords, heading)
    -- Save to database
    MySQL.Async.execute('UPDATE vehicles SET x = @x, y = @y, z = @z, heading = @heading WHERE plate = @plate', {
        ['@x'] = coords.x,
        ['@y'] = coords.y,
        ['@z'] = coords.z,
        ['@heading'] = heading,
        ['@plate'] = plate
    })
end)

Conclusion

Vehicle scripting in FiveM opens up endless possibilities for creating immersive experiences. From basic spawning to advanced management systems, these techniques will help you build professional vehicle scripts for your server.

Need Custom Vehicle Scripts?

Our AI script generator can create professional vehicle scripts tailored to your specific needs. Generate optimized scripts in seconds.

Try AI Generator