Véhicules

Des voitures, camions, avions, hélicoptères et bateaux qu'on conduit à plusieurs, et un éditeur pour créer les siens en important un modèle 3D et en réglant tout : roues, moteur, boîte, suspension, vol, flottaison, hélices, places, sons et feux. Un véhicule reste un prop : physgun, toolgun, dupes et éditeur de map marchent avec.

Conduire

ToucheAction
E en visant un véhiculeMonter (place du conducteur si elle est libre, sinon la place libre la plus proche) ; E encore pour descendre. On monte et on descend les mains vides : l'arme est rangée, et revient en main une fois debout à côté de la portière (bouger, tirer ou changer d'arme écourte la descente).
Z Q S D (AZERTY)Accélérer, tourner, freiner puis reculer
EspaceFrein à main
CCaméra 3e personne (la souris tourne autour du véhicule) ou retour à la vue intérieure
L / HPhares / klaxon
← → / ↓Clignotants / warnings
Maj / CtrlMonter / descendre un rapport (boîte manuelle)

Les touches se changent dans Configuration → Options. Les véhicules du jeu (berline, pick-up, avion de tourisme, hélicoptère léger, bateau à moteur) et ceux des addons sont dans l'onglet Véhicules du menu de spawn. Les feux stop et de recul s'allument seuls.

Avions, hélicoptères et bateaux

Le pilotage est « arcade » façon GMod : stabilisé et facile à prendre en main. Une jauge en bas de l'écran du pilote montre les gaz, la vitesse, l'altitude et les touches.

TypeTouchesComportement
AvionZ / S : gaz + / − (la manette reste où on la laisse) · Q / D : roulis · Espace / Ctrl : cabrer / piquer · G : train rentrant · S gaz à zéro au sol : freinsAu sol il roule sur son train (la roue avant tourne avec Q / D). Les ailes portent tout son poids à partir de la vitesse de décrochage : c'est sa vitesse de décollage ; en dessous, en l'air, il pique du nez. En vol il va là où pointe son nez, vire en s'inclinant et revient à plat (ailes et tangage) quand on lâche les touches.
HélicoptèreEspace / Ctrl : monter / descendre · Z / S : avancer / reculer · Q / D : tournerLe rotor démarre quand le pilote monte (quelques secondes avant de pouvoir décoller) et s'arrête quand il descend. Il se penche pour avancer, se remet droit et freine seul quand on lâche les touches, et garde son altitude sans rien toucher.
BateauZ / S : gaz / marche arrière · Q / D : gouvernailIl flotte sur les volumes d'eau des maps (ceux de l'éditeur de map et des maps du jeu), tangue sur des points de la coque, et son hélice ne pousse que quand elle est sous l'eau. Il tourne mieux avec de la vitesse.

Dans un avion, un hélicoptère ou un bateau, les passagers penchent avec l'appareil (loopings compris). Les feux de navigation (rouge à gauche, vert à droite), à éclats et anticollision s'allument tant que le moteur tourne ; les hélices et rotors tournent avec le régime, les gouvernes suivent les commandes.

MultijoueurC'est l'ordinateur du conducteur qui calcule la voiture : elle réagit tout de suite, même avec du ping. Le serveur vérifie ce qu'il reçoit (pas de téléportation) et les autres joueurs la voient suivre. Sans conducteur, le serveur la simule (elle peut rouler en pente, être poussée, tractée…).

Créer un véhicule

  1. Créer → Véhicules → Nouveau pack. Un pack de véhicules est un addon local, publiable sur le Workshop, avec un premier véhicule.
  2. Un pack, plusieurs véhicules : la liste à gauche de l'éditeur montre les véhicules du pack. Nouveau en ajoute un, Dupliquer copie celui sélectionné avec ses réglages (pratique pour une variante), Supprimer le retire (son fichier part à la corbeille à l'enregistrement). Le nom se change dans les réglages ; à son premier enregistrement, un nouvel élément prend un fichier à son nom (vehicles/taxi.json).
  3. Choisis le type en haut de l'onglet Véhicule : voiture / camion, avion, hélicoptère ou bateau. Changer de type remet les réglages propres à ce type (poussée, vitesses, son…) ; la carrosserie, les roues et les places restent. Le bouton Repartir de… (onglet Véhicule) place un train tricycle (avion), des patins (hélicoptère) ou aucune roue (bateau).
  4. Importer la carrosserie… (glTF, GLB ou FBX). L'avant doit regarder vers -Z, le sol être à Y = 0 ; sinon corrige dans l'onglet Véhicule (rotation, décalage, échelle). Un premier import place les roues et 2 places à la taille du modèle selon le type. L'import et l'ouverture d'un véhicule se font derrière un écran de chargement : le modèle est lu et ses collisions calculées en arrière-plan.
  5. Place les roues et les places : clique un repère dans la vue et tire les flèches, ou tape les valeurs. Avec Symétrie, le côté opposé suit.
  6. Prends la miniature du Workshop avec Photo Workshop (les repères et mannequins sont cachés ; sans photo, une photo automatique est prise à la publication).
  7. Règle le moteur, le châssis, les sons et les feux, puis Tester : une partie solo démarre au volant. Quitter la partie ramène dans l'éditeur.

Repères de la vue : jaune = roues (avec la course de suspension), bleu = places (avec un mannequin assis), vert = sorties, rouge = centre de gravité, crème = phares, turquoise = hélice d'un bateau. La fiche à gauche calcule la puissance, la vitesse max théorique et le rapport poids/puissance (voiture), ou la poussée par rapport au poids, la vitesse max et de décrochage (avion), la montée (hélicoptère), l'enfoncement (bateau). Dans la vue, les hélices et rotors tournent lentement pour vérifier leur axe.

Onglets de réglages

OngletContenu
VéhiculeNom et catégorie dans le menu de spawn, échelle / rotation / décalage du modèle, collision (formes exactes ou boîte), matière, pièces cachées (par exemple des roues soudées à la carrosserie qu'on remplace)
RouesModèle de roue (pneu du jeu, cylindre simple ou un modèle importé, mis à l'échelle du rayon), puis pour chaque roue : centre, rayon, largeur, directrice, motrice, freinée, frein à main, retournée (côté gauche), ou une pièce du modèle qui tourne comme une roue (Caler sur la pièce la mesure)
MoteurCouple, ralenti, régime max (rupteur), frein moteur, courbe de couple (points éditables), boîte automatique ou manuelle, rapports (avec la vitesse max de chacun), marche arrière, pont, temps de passage, seuils de passage, vitesse bridée
ChâssisMasse, centre de gravité, débattement, raideur, amortissement, barre anti-roulis, adhérence avant / arrière, résistance au roulement, frein à main, angle et vitesse de braquage, braquage réduit à haute vitesse, couple de freinage, traînée, appui
PlacesPosition (sous les fesses du mannequin assis), orientation, point de sortie ; la place 1 est celle du conducteur. Volant / manche : pièce du modèle tournée par la direction, rotation en braquage complet, rayon et écart des prises (les mains du conducteur la suivent). Distance et hauteur de la caméra 3e personne
Sons & feuxSon moteur synthétisé (cylindres, tonalité ; pales pour un avion ou un hélicoptère : bourdonnement d'hélice ou battement de rotor avec sifflement de turbine) ou un fichier en boucle dont la vitesse suit le régime ; klaxon ; pièces du modèle qui s'allument pour les phares, feux stop, recul et clignotants, et (avions, hélicoptères, bateaux) feux de navigation rouge / vert, feux à éclats et anticollision ; faisceaux des phares (vraies lumières) et points de phare

Pour un avion ou un hélicoptère, les onglets Roues et Moteur deviennent Train et Vol ; pour un bateau, Moteur et Châssis deviennent Navigation et Coque :

OngletContenu
Train (avion, hélicoptère)Les mêmes roues que pour une voiture, sans moteur : la roue directrice tourne au sol, les roues freinées freinent. Train rentrant (avion, touche G) : les roues disparaissent en vol. Décoche Visible pour un patin : un point d'appui sans roue dessinée
Vol (avion)Poussée max (N), vitesse max, vitesse de décrochage (= décollage), vitesses de tangage, roulis et virage (°/s), tenue de trajectoire (l'avion va où pointe son nez), retour à plat
Vol (hélicoptère)Vitesse de montée (m/s), démarrage du rotor (s), inclinaison max, vitesse max (atteinte penché au maximum), rotation (°/s), stabilisation (remise à plat et freinage quand on lâche)
Navigation (bateau)Poussée max, vitesse max, position de l'hélice (repère turquoise, elle ne pousse que sous l'eau), gouvernail (°/s), quille (anti-dérapage), flottaison : enfoncement (profondeur du bas de la coque au repos) et flottabilité (en dessous de 0,4 environ, il coule)
Vol / Navigation : pièces animéesHélices et rotors : pièces du modèle qui tournent autour de leur centre avec le régime (axe X, Y ou Z, tours par seconde à plein régime ; pas de collision). Gouvernes : pièces qui s'inclinent avec une commande (tangage, roulis ou lacet), autour de leur centre, jusqu'à un angle max (négatif = dans l'autre sens, par exemple l'aileron droit). Régime de ralenti et plein régime (ou régime du rotor)

Placer les sièges et le volant

Assis, le mannequin prend une pose de siège auto : jambes allongées vers les pédales, dos incliné, mains au volant pour le conducteur, sur les cuisses pour les passagers. Par rapport à la position d'une place (avant vers -Z, en mètres) :

RepèrePosition
Hanches[0, 0.54, 0.33] (l'assise du siège vers y = 0.44)
Talons (plancher)y = 0.18, environ 0,7 m devant les hanches
Haut de la têtevers y = 1.35 : prévois le toit au-dessus de 1.40
Yeux (vue à la 1re personne)[0, 1.26, 0.36]
Centre du volant[0, 0.88, -0.03], incliné de 25° (le haut vers l'avant), rayon 0,19 m

Le volant est une pièce du modèle ("steering_wheel") dont l'origine est au centre et dont l'axe Y local pointe vers le conducteur (« midi » vers -Z local). Elle tourne de steering_wheel_angle degrés en braquage complet ; les mains la tiennent à steering_wheel_radius du centre, steering_wheel_grip degrés de part et d'autre de midi (60 : 10 h 10), et la suivent jusqu'à 100° (au-delà, le volant glisse dans les mains). La même clé sert pour un manche d'avion à cornes ou un cyclique d'hélicoptère en T (origine au pied du manche : il s'incline sur le côté).

"steering_wheel": "Volant", "steering_wheel_angle": 270, "steering_wheel_radius": 0.19, "steering_wheel_grip": 60

Les véhicules du jeu sont construits dans Blender par des scripts (assets/_source/vehicle_scripts/, voir le LISEZMOI.md) qui reprennent ces repères : ils servent d'exemples.

SuspensionLe véhicule repose toujours à la hauteur où les roues sont dessinées : la raideur ne règle que la souplesse. Pour une voiture qui tient la route, garde le centre de gravité bas et l'adhérence arrière un peu plus forte que l'avant ; pour un véhicule de drift, fais l'inverse.

Fichiers d'un véhicule

ma_voiture/
├── addon.json
├── vehicles/
│   ├── vehicle.json      réglages du premier véhicule (écrits par l'éditeur)
│   ├── taxi.json         un autre véhicule du pack
│   ├── carrosserie.glb   modèles importés (partagés par tout le pack)
│   └── roue.glb          modèle de roue (facultatif)
└── sound/
    └── ma_voiture/       sons importés (moteur, klaxon)

Son identifiant (menu de spawn, Lua, dupes, maps) est addon:<clé>/vehicles/vehicle.json, par exemple addon:local_ma_voiture/vehicles/vehicle.json. Ceux du jeu sont vehicle:sedan, vehicle:pickup, vehicle:plane, vehicle:helicopter et vehicle:boat. Chaque fichier JSON de vehicles/ est un véhicule (addon:local_ma_voiture/vehicles/taxi.json…) et l'éditeur les ouvre tous. Les chemins de modèles sont relatifs au fichier JSON ; les sons se cherchent comme pour EmitSound.

vehicle.json

Toutes les clés sont facultatives (valeurs par défaut sinon). Positions en mètres, [x, y, z], avant vers -Z.

{
	"name": "Ma voiture", "category": "Véhicules",
	"model": "carrosserie.glb", "model_scale": 1.0, "model_rotation": [0, 0, 0], "model_offset": [0, 0, 0],
	"hidden_parts": ["Roues_Soudees"], "collision": "convex", "mass": 1300, "center_of_mass": [0, 0.45, 0],
	"wheel_model": "builtin:tire", "wheel_model_rotation": [0, 90, 0],
	"wheels": [
		{"pos": [-0.8, 0.33, -1.4], "radius": 0.33, "width": 0.22, "steer": true, "drive": true, "brake": true, "handbrake": false, "flip": true, "part": ""}
	],
	"suspension_travel": 0.22, "spring": 38000, "damping": 3800, "anti_roll": 9000,
	"grip": 1.35, "grip_rear": 1.35, "steer_angle": 33,
	"engine_torque": 340, "idle_rpm": 850, "max_rpm": 6500, "torque_curve": [0.55, 0.8, 0.97, 1.0, 0.82],
	"gearbox": "auto", "gears": [3.6, 2.15, 1.45, 1.08, 0.86, 0.72], "reverse_gear": 3.4, "final_drive": 3.9,
	"brake_torque": 2600, "handbrake_torque": 3500, "drag": 0.38, "downforce": 0.6,
	"seats": [{"pos": [-0.4, 0.15, 0.1], "yaw": 0, "exit": [-1.7, 0, 0.1]}],
	"steering_wheel": "Volant", "steering_wheel_angle": 270, "steering_wheel_radius": 0.19, "steering_wheel_grip": 60,
	"engine_sound": "synth", "synth_cylinders": 4, "horn_sound": "physicore/klaxon.wav",
	"lights": {"headlights": ["Phare_G", "Phare_D"], "brake": ["Feu_Stop"], "reverse": [], "left": [], "right": []},
	"headlight_points": []
}

"type" vaut "car" (par défaut), "plane", "helicopter" ou "boat". Les autres types ajoutent ces clés (vitesses en km/h, rotations en degrés par seconde ; une clé absente prend la valeur par défaut du type) :

{
	"type": "plane",
	"thrust": 5500, "max_speed": 280, "stall_speed": 95,
	"pitch_rate": 50, "roll_rate": 100, "yaw_rate": 30, "alignment": 2.5, "auto_level": 0.5,
	"retractable_gear": false,
	"climb_speed": 8, "tilt_angle": 22, "spool_time": 4,
	"draft": 0.3, "buoyancy": 1.0, "propeller_pos": [0, 0.1, 2.0],
	"spinners": [{"part": "Helice", "axis": "z", "speed": 12}],
	"surfaces": [{"part": "Aileron_G", "axis": "x", "input": "roll", "angle": 20},
	             {"part": "Profondeur", "axis": "x", "input": "pitch", "angle": -25}],
	"wheels": [{"pos": [0, 0.08, -0.9], "radius": 0.08, "visible": false}],
	"synth_cylinders": 2,
	"lights": {"nav_red": ["Feu_G"], "nav_green": ["Feu_D"], "strobe": ["Flash"], "beacon": ["Gyro"]}
}

climb_speed, tilt_angle et spool_time servent à l'hélicoptère, draft, buoyancy et propeller_pos au bateau, stall_speed, pitch_rate, roll_rate et retractable_gear à l'avion. input d'une gouverne : "pitch", "roll" ou "yaw" ; axis : "x", "y" ou "z". synth_cylinders est le nombre de pales pour un avion ou un hélicoptère.

En Lua

Créer et contrôler

FonctionCôtéEffet
ents.CreateVehicle(id, position, angle)serveurFait apparaître un véhicule ("vehicle:sedan"…), angle en degrés autour de Y. Renvoie l'entité.
veh:IsVehicle()partagéEst-ce un véhicule ? (veh:GetClass() vaut "prop_vehicle")
veh:GetDriver(), veh:GetPassengers()partagéConducteur (ou nil), table des passagers
veh:GetSeatCount()partagéNombre de places
veh:GetSpeed(), veh:GetRPM(), veh:GetGear()partagéVitesse en km/h, régime, rapport (-1 = marche arrière)
veh:GetVehicleType()partagé"car", "plane", "helicopter" ou "boat"
veh:GetPower()partagé0..1 : manette des gaz (avion), vitesse du rotor (hélicoptère), régime (bateau)
veh:SetLandingGear(bool), veh:IsLandingGearDown()serveur / partagéSort (true) ou rentre le train d'un avion à train rentrant
veh:SetLocked(bool), veh:IsLocked()serveur / partagéVerrouille : personne ne peut monter
veh:SetThrottle(-1..1), veh:SetSteering(-1..1), veh:SetBrake(0..1)serveurConduite par script quand personne n'est au volant (IA, taxis…) ; nil rend la main. Comme les touches : pour un avion, SetThrottle pousse la manette des gaz ; pour un hélicoptère il le fait avancer / reculer
veh:SetLift(-1..1)serveurPar script : monter / descendre (hélicoptère), cabrer / piquer (avion) ; nil rend la main
veh:SetHandbrake(bool), veh:SetHorn(bool), veh:SetHeadlights(bool)serveurFrein à main, klaxon, phares
veh:EjectAll()serveurFait descendre tout le monde
ply:InVehicle(), ply:GetVehicle(), ply:GetVehicleSeat()partagéDans un véhicule ? lequel ? quelle place (1 = conducteur, 0 = à pied)
ply:EnterVehicle(veh, place), ply:ExitVehicle()serveurFait monter (place 0 = la meilleure libre) / descendre

Les méthodes des props marchent aussi (SetColor, SetFrozen, GetNodeNames, SetNodeEmission…), voir Player et Entity.

Hooks

HookArgumentsRetour
CanPlayerEnterVehicleply, veh, placefalse pour refuser
PlayerEnteredVehicleply, veh, place—
PlayerLeaveVehicleply, veh—
-- Serveur : seuls les policiers (équipe 2) conduisent les voitures de police.
hook.Add("CanPlayerEnterVehicle", "police", function(ply, veh, place)
	if veh:GetNWBool("police") and place == 1 and ply:Team() ~= 2 then
		ply:ChatPrint("Réservé à la police.")
		return false
	end
end)

-- Un taxi qui roule tout droit tant que personne ne le conduit.
local taxi = ents.CreateVehicle("vehicle:sedan", Vector(0, 1, 0), 90)
taxi:SetThrottle(0.4)
timer.Simple(5, function() taxi:SetThrottle(nil) taxi:SetBrake(1) end)

-- Un hélicoptère qui décolle seul (le rotor démarre d'abord), puis avance.
local heli = ents.CreateVehicle("vehicle:helicopter", Vector(20, 1, 0), 0)
heli:SetLift(1)
timer.Simple(8, function() heli:SetLift(0) heli:SetThrottle(0.5) end)