Chapter 6.2: Vehicle System
Domů | << Předchozí: Systém entit | Vozidla | Další: Počasí >>
Úvod
DayZ vehicles are entities that extend the transport system. Cars extend CarScript, boats extend BoatScript, and oba inherit from Transport. Vehicles have fluid systems, parts with nezávislý health, gear simulation, and physics managed by engine. This chapter covers the API methods potřebujete to interact with vehicles in scripts.
Hierarchie tříd
EntityAI
└── Transport // 3_Game - base for all vehicles
├── Car // 3_Game - engine-native car physics
│ └── CarScript // 4_World - scriptable car base
│ ├── CivilianSedan
│ ├── OffroadHatchback
│ ├── Hatchback_02
│ ├── Sedan_02
│ ├── Truck_01_Base
│ └── ...
└── Boat // 3_Game - engine-native boat physics
└── BoatScript // 4_World - scriptable boat baseTransport (základ)
Soubor: 3_Game/entities/transport.c
Abstraktní základ pro všechna vozidla. Poskytuje správu sedadel a přístup k posádce.
Správa posádky
proto native int CrewSize(); // Total number of seats
proto native int CrewMemberIndex(Human crew_member); // Get seat index of a human
proto native Human CrewMember(int posIdx); // Get human at seat index
proto native void CrewGetOut(int posIdx); // Force crew member out of seat
proto native void CrewDeath(int posIdx); // Kill crew member in seatNastupování posádky
proto native int GetAnimInstance();
proto native int CrewPositionIndex(int componentIdx); // Component to seat index
proto native vector CrewEntryPoint(int posIdx); // World entry position for seatPříklad --- eject all passengers:
void EjectAllCrew(Transport vehicle)
{
for (int i = 0; i < vehicle.CrewSize(); i++)
{
Human crew = vehicle.CrewMember(i);
if (crew)
{
vehicle.CrewGetOut(i);
}
}
}Car (nativní engine)
Soubor: 3_Game/entities/car.c
Fyzika auta na úrovni enginu. Všechny proto native metody, které řídí simulaci vozidla.
Motor
proto native bool EngineIsOn();
proto native void EngineStart();
proto native void EngineStop();
proto native float EngineGetRPM();
proto native float EngineGetRPMRedline();
proto native float EngineGetRPMMax();
proto native int GetGear();Kapaliny
Vozidla DayZ mají čtyři typy kapalin definované ve CarFluid enum:
enum CarFluid
{
FUEL,
OIL,
BRAKE,
COOLANT
}proto native float GetFluidCapacity(CarFluid fluid);
proto native float GetFluidFraction(CarFluid fluid); // 0.0 - 1.0
proto native void Fill(CarFluid fluid, float amount);
proto native void Leak(CarFluid fluid, float amount);
proto native void LeakAll(CarFluid fluid);Příklad --- refuel a vehicle:
void RefuelVehicle(Car car)
{
float capacity = car.GetFluidCapacity(CarFluid.FUEL);
float current = car.GetFluidFraction(CarFluid.FUEL) * capacity;
float needed = capacity - current;
car.Fill(CarFluid.FUEL, needed);
}Rychlost
proto native float GetSpeedometer(); // Speed in km/h (absolute value)Ovládání (simulace)
proto native void SetBrake(float value, int wheel = -1); // 0.0 - 1.0, -1 = all wheels
proto native void SetHandbrake(float value); // 0.0 - 1.0
proto native void SetSteering(float value, bool analog = true);
proto native void SetThrust(float value, int wheel = -1); // 0.0 - 1.0
proto native void SetClutchState(bool engaged);Kola
proto native int WheelCount();
proto native bool WheelIsAnyLocked();
proto native float WheelGetSurface(int wheelIdx);Zpětná volání (přepsat v CarScript)
void OnEngineStart();
void OnEngineStop();
void OnContact(string zoneName, vector localPos, IEntity other, Contact data);
void OnFluidChanged(CarFluid fluid, float newValue, float oldValue);
void OnGearChanged(int newGear, int oldGear);
void OnSound(CarSoundCtrl ctrl, float oldValue);CarScript
Soubor: 4_World/entities/vehicles/carscript.c
The scriptable car class that většina vehicle mods extend. Adds parts, doors, lights, and sound management.
Zdraví dílů
CarScript uses damage zones to represent vehicle parts. Each part can be nezávisle damaged:
// Check part health via the standard EntityAI API
float engineHP = car.GetHealth("Engine", "Health");
float fuelTankHP = car.GetHealth("FuelTank", "Health");
// Set part health
car.SetHealth("Engine", "Health", 0); // Destroy the engine
car.SetHealth("FuelTank", "Health", 100); // Repair the fuel tankDiagram zón poškození
Běžné damage zones for vehicles:
| Zone | Description |
|---|---|
"" (globální) | Overall vehicle health |
"Engine" | Engine part |
"FuelTank" | Fuel tank |
"Radiator" | Radiator (coolant) |
"Battery" | Battery |
"SparkPlug" | Spark plug |
"FrontLeft" / "FrontRight" | Front wheels |
"RearLeft" / "RearRight" | Rear wheels |
"DriverDoor" / "CoDriverDoor" | Front doors |
"Hood" / "Trunk" | Hood and trunk |
Světla
void SetLightsState(int state); // 0 = off, 1 = on
int GetLightsState();Ovládání dveří
bool IsDoorOpen(string doorSource);
void OpenDoor(string doorSource);
void CloseDoor(string doorSource);Klíčová přepsání pro vlastní vozidla
override void EEInit(); // Initialize vehicle parts, fluids
override void OnEngineStart(); // Custom engine start behavior
override void OnEngineStop(); // Custom engine stop behavior
override void EOnSimulate(IEntity other, float dt); // Per-tick simulation
override bool CanObjectAttachWeapon(string slot_name);Příklad --- create a vehicle with plný fluids:
void SpawnReadyVehicle(vector pos)
{
Car car = Car.Cast(GetGame().CreateObjectEx("CivilianSedan", pos,
ECE_PLACE_ON_SURFACE | ECE_INITAI | ECE_CREATEPHYSICS));
if (!car)
return;
// Fill all fluids
car.Fill(CarFluid.FUEL, car.GetFluidCapacity(CarFluid.FUEL));
car.Fill(CarFluid.OIL, car.GetFluidCapacity(CarFluid.OIL));
car.Fill(CarFluid.BRAKE, car.GetFluidCapacity(CarFluid.BRAKE));
car.Fill(CarFluid.COOLANT, car.GetFluidCapacity(CarFluid.COOLANT));
// Spawn required parts
EntityAI carEntity = EntityAI.Cast(car);
carEntity.GetInventory().CreateAttachment("CarBattery");
carEntity.GetInventory().CreateAttachment("SparkPlug");
carEntity.GetInventory().CreateAttachment("CarRadiator");
carEntity.GetInventory().CreateAttachment("HatchbackWheel");
}BoatScript
Soubor: 4_World/entities/vehicles/boatscript.c
Skriptovatelný základ pro entity lodí. Podobné API jako CarScript, ale s fyzikou založenou na vrtuli.
Motor a pohon
proto native bool EngineIsOn();
proto native void EngineStart();
proto native void EngineStop();
proto native float EngineGetRPM();Kapaliny
Boats use the stejný CarFluid enum but typicky pouze use FUEL:
float fuel = boat.GetFluidFraction(CarFluid.FUEL);
boat.Fill(CarFluid.FUEL, boat.GetFluidCapacity(CarFluid.FUEL));Rychlost
proto native float GetSpeedometer(); // Speed in km/hPříklad --- spawn a boat:
void SpawnBoat(vector waterPos)
{
BoatScript boat = BoatScript.Cast(
GetGame().CreateObjectEx("Boat_01", waterPos,
ECE_CREATEPHYSICS | ECE_INITAI)
);
if (boat)
{
boat.Fill(CarFluid.FUEL, boat.GetFluidCapacity(CarFluid.FUEL));
}
}Kontroly interakce s vozidlem
Kontrola, zda je hráč ve vozidle
PlayerBase player;
if (player.IsInVehicle())
{
EntityAI vehicle = player.GetDrivingVehicle();
CarScript car;
if (Class.CastTo(car, vehicle))
{
float speed = car.GetSpeedometer();
Print(string.Format("Driving at %1 km/h", speed));
}
}Nalezení všech vozidel ve světě
void FindAllVehicles(out array<Transport> vehicles)
{
vehicles = new array<Transport>;
array<Object> objects = new array<Object>;
array<CargoBase> proxyCargos = new array<CargoBase>;
// Use a large radius from center of map
GetGame().GetObjectsAtPosition(Vector(7500, 0, 7500), 15000, objects, proxyCargos);
foreach (Object obj : objects)
{
Transport transport;
if (Class.CastTo(transport, obj))
{
vehicles.Insert(transport);
}
}
}Shrnutí
| Koncept | Klíčový bod |
|---|---|
| Hierarchy | Transport > Car/Boat > CarScript/BoatScript |
| Engine | EngineStart(), EngineStop(), EngineIsOn(), EngineGetRPM() |
| Fluids | CarFluid enum: FUEL, OIL, BRAKE, COOLANT |
| Fill/Leak | Fill(fluid, amount), Leak(fluid, amount), GetFluidFraction(fluid) |
| Speed | GetSpeedometer() returns km/h |
| Crew | CrewSize(), CrewMember(idx), CrewGetOut(idx) |
| Parts | Standard damage zones: "Engine", "FuelTank", "Radiator", etc. |
| Creation | CreateObjectEx with ECE_PLACE_ON_SURFACE | ECE_INITAI | ECE_CREATEPHYSICS |
| 1.28 Config | useNewNetworking, wheelHubFriction, zdvojnásobené hodnoty brzdného momentu |
| 1.28 Physics | Aktualizovaný Bullet Physics, nová pole API Contact, odpružení vždy aktivní |
| 1.29 Experimental | Multithreading fyziky, Transport sleep, dynamická kolize pro všechny transport |
Osvědčené postupy
- Vždy include
ECE_CREATEPHYSICS | ECE_INITAIwhen spawning vehicles. Bez physics, the vehicle falls through the ground. Bez AI init, engine simulation ne start and the vehicle nemůže být driven. - Fill all four fluids after spawning. A vehicle chybějící oil, brake fluid, or coolant will damage itself okamžitě when engine starts. Use
GetFluidCapacity()to get correct max values per vehicle type. - Null-check
CrewMember()before operating on crew. Empty seats returnnull. IteratingCrewSize()without checking každý index causes crashes when seats are unoccupied. - Use
GetSpeedometer()místo computing velocity ručně. Engine's speedometer accounts for wheel contact, transmission state, and physics správně. Manual velocity calculations from position deltas are unreliable.
Kompatibilita a dopad
Kompatibilita modů: Vehicle mods běžně extend
CarScriptwith modded classes. Conflicts arise when více mods override the stejný zpětné volánís likeOnEngineStart()orEOnSimulate().
- Pořadí načítání: If two mods both
modded class CarScriptand overrideOnEngineStart(), only the last-loaded mod runs unless both callsuper. Vehicle overhaul mods should always callsuperin every callback. - Konflikty modifikovaných tříd: Expansion Vehicles and vanilla vehicle mods frequently conflict on
EEInit()and fluid initialization. Testujte with oba loaded. - Dopad na výkon:
EOnSimulate()runs každý physics tick for každý active vehicle. Udržujte logic minimal in this zpětné volání; use timer accumulators for expensive operations. - Server/klient:
EngineStart(),EngineStop(),Fill(),Leak(), andCrewGetOut()are server-authoritative.GetSpeedometer(),EngineIsOn(), andGetFluidFraction()are safe to read na obou stranách.
Pozorováno v reálných modech
These patterns were confirmed by studying the source code of professional DayZ mods.
| Vzor | Mod | Soubor/Umístění |
|---|---|---|
Override EEInit() to set vlastní fluid capacities and spawn parts | Expansion Vehicles | CarScript subclasses |
EOnSimulate accumulator for periodic fuel consumption checks | Vanilla+ vehicle mods | CarScript overrides |
CrewGetOut() loop in admin eject-all command | VPP Admin Tools | Vehicle management module |
Custom OnContact() override for collision damage tuning | Expansion | ExpansionCarScript |
Změny konfigurace vozidel (1.28+)
Upozornění (1.28): DayZ 1.28 přinesl významné změny fyziky vozidel. Pokud aktualizujete mod vozidel z verze 1.27 nebo starší, pečlivě si přečtěte tuto sekci.
Parametr useNewNetworking
DayZ 1.28 přidal konfigurační parametr useNewNetworking pro všechny třídy CarScript. Výchozí hodnota je 1 (povoleno).
class CfgVehicles
{
class CarScript;
class MyVehicle : CarScript
{
// Nový networking zlepšuje gumování při vysokém pingu
useNewNetworking = 1; // výchozí — pro většinu modů ponechte povoleno
// Zakažte POUZE pokud váš mod modifikuje fyziku vozidel
// mimo konfiguraci SimulationModule:
// useNewNetworking = 0;
};
};Kdy zakázat: Pokud váš mod přímo manipuluje s fyzikou vozidel přes skript (vlastní přepisování EOnSimulate, přímé aplikování sil, vlastní logika kol) namísto přes konfiguraci SimulationModule, nový systém rekonciliace může bojovat s vašimi změnami. V takovém případě nastavte useNewNetworking = 0;.
Parametr wheelHubFriction (1.28+)
Nová konfigurační proměnná, která definuje odpor nápravy, když nejsou připojena žádná kola:
class SimulationModule
{
class Axles
{
class Front
{
wheelHubFriction = 0.5; // Jak rychle vozidlo zpomaluje bez kol
};
};
};Migrace brzdného momentu (1.28)
Narušující změna: Před verzí 1.28 se brzdný a ruční brzdný moment aplikoval dvakrát kvůli chybě. Ve verzi 1.28 to bylo opraveno. Pokud migrujete mod vozidla, zdvojnásobte hodnoty
maxBrakeTorqueamaxHandbrakeTorquepro zachování stejného pocitu brzdění.
// Před 1.28 (chyba: aplikováno dvakrát, takže efektivní hodnota byla 2x)
maxBrakeTorque = 2000;
maxHandbrakeTorque = 3000;
// Po 1.28 (oprava: aplikováno jednou, takže zdvojnásobte pro zachování starého chování)
maxBrakeTorque = 4000;
maxHandbrakeTorque = 6000;Odpružení vždy aktivní (1.28+)
Odpružení vozidla je nyní vždy aktivní, dokud je vozidlo probuzené. Předtím mohlo být odpružení v určitých stavech neaktivní. To zlepšuje stabilitu, ale může změnit pocit vlastního nastavení odpružení.
Aktualizace Bullet Physics (1.28)
Knihovna Bullet Physics byla aktualizována na nejnovější verzi Enfusion. Mohou se vyskytnout jemné rozdíly v kolizní odezvě, tření a restituci. Důkladně otestujte všechny vlastní konfigurace vozidel.
Změny API fyzických kontaktů (1.28)
Třída Contact byla upravena:
Odstraněno:
MaterialIndex1,MaterialIndex2Index1,Index2
Přidáno:
ShapeIndex1,ShapeIndex2--- identifikují, který tvar ve složeném tělese byl zasaženVelocityBefore1,VelocityBefore2--- rychlosti před kolizíVelocityAfter1,VelocityAfter2--- rychlosti po kolizi
Změněno:
Material1,Material2--- typ změněn zdMaterialnaSurfaceProperties
Mody, které čtou data Contact v EOnContact, musí aktualizovat názvy a typy nových proměnných.
Změny vozidel v 1.29 (experimentální)
Poznámka: Tyto změny pochází z DayZ 1.29 experimentálního a mohou se před stabilní verzí změnit.
Multithreading Bullet Physics (1.29 experimentální)
Pro knihovnu Bullet Physics byla povolena podpora multithreadingu. Stresové testy serveru ukázaly až 400% zlepšení FPS (z 9 FPS na 50 FPS). Mody vozidel, které se spoléhají na specifické časování fyziky nebo volají funkce fyziky z callbacků skriptů, by měly být důkladně otestovány.
Transport Sleep (1.29 experimentální)
Na Transport byly přidány fyzikální funkce umožňující vozidlům usnout, když jsou v klidu. Neaktivní tělesa již nepřijímají callbacky EOnSimulate / EOnPostSimulate. Pokud se váš mod vozidla spoléhá na to, že tyto callbacky běží nepřetržitě, otestujte na 1.29 experimentálním.
Dynamická kolize pro všechny Transport (1.29 experimentální)
Třída Transport (rodič CarScript a BoatScript) má nyní dynamické řešení kolizí. Předtím to měl pouze CarScript. Mody lodí těží ze správného zpracování kolizí.
Domů | << Předchozí: Systém entit | Vozidla | Další: Počasí >>
