




















































Over 100 recipes written by Crytek developers for creating AAA games using the technology that created Crysis 2
In this recipe, we will show you how to build the basic mesh structure for your car to be used in the next recipe. This recipe is not to viewed as a guide on how to model your own mesh, but rather as a template for how the mesh needs to be structured to work with the XML script of the vehicle. For this recipe, you will be using 3DSMax to create and export your .CGA.
.CGA (Crytek Geometry Animation): The .cga file is created in the 3D application and contains animated hard body geometry data. It only supports directly-linked objects and does not support skeleton-based animation (bone animation) with weighted vertices. It works together with .anm files.
Create a box primitive and four cylinders within Max and then create a new dummy helper.
After creating the basic primitives within Max, we need to rename these objects. Rename the primitives to match the following naming convention:
Remember that CryENGINE 3 assumes that y is forward. Rotate and reset any x-forms if necessary.
From here you can now set up the hierarchy to match what we will build into the script:
Your hierarchy should look like the following screenshot in the Max schematic view:
Next, you will want to create a proxy mesh for each wheel and the body. Be sure to attach these proxies to each mesh. Proxy meshes can be a direct duplication of the simple primitive geometry we have created.
Before we export this mesh, make one final adjustment to the positioning of the vehicle:
Once complete, your left viewport should look something like the following screenshot (if you have your body still selected):
After setting up the materials, you are now ready to export the CGA:
This setup of the CGA is a basic setup of the majority of the four wheeled vehicles used for CryENGINE 3. This same basic setup can also be seen in the HMMWV provided in the included assets with the SDK package of CryENGINE 3.
Even though the complete HMMWV may seem to be a very complicated mesh used as a vehicle, it can also be broken down into the same basic structure as the vehicle we just created.
The main reason for the separation of the parts on the vehicles is because each part performs its own function. Since the physics of the vehicle code drives the vehicle forward in the engine, it actually controls each wheel independently, so it can animate them based on what they can do at that moment. This means that you have the potential for a four wheel drive on all CryENGINE 3 vehicles, all animating at different speeds based on the friction that they grip.
Since all of the wheels are parented to the body (or hull) mesh, this means that they drive their parent (the body of the vehicle) but the body also handles where the wheels need to be offset from in order to stay aligned when driving. The body itself acts as the base mesh for all other extras put onto the vehicle. Everything else from Turrets to Doors to Glass Windows branch out from the body.
The dummy helper is only the parent for the body mesh due to the fact that it is easier to export multiple LODs for that vehicle (for example, HMMWV, HMMWV_LOD1, HMMWV_LOD2, and so on). In the XML, this dummy helper is ignored in the hierarchy and the body is treated as the parent node.
Here are some of the more advanced techniques used.
A more advanced trick is the use of dummy helpers set inside the hierarchy to be used in later reference through the vehicle's mod system. How this works is that if you had a vehicle such as the basic car shown previously, but you wanted to add on an additional mesh just to have a modified type of this same car (something like adding a spoiler to the back), then you can create a dummy helper and align it to the pivot of the object, so it will line up to the body of the mesh when added through the script later on.
This same method was used in Crysis 2 with the Taxi signs on the top of the Taxi cars. The Taxi itself was the same model used as the basic civilian car, but had an additional dummy helper where the sign needed to be placed. This allowed for a clever way to save on memory when rendering multiple vehicle props within a single area but making each car look different.
Adding the basic body and four wheels to make a basic car model is only the beginning. There are limitless possibilities to what you can make as far as the parts on a vehicle are concerned. Anything from a classic gunner turret seen on the HMMWV or even tank turrets, all the way to arms for an articulated Battlemech as seen in the Crysis 2 Total Conversion mod—MechWarrior: Living Legends. Along with the modifications system, you have the capabilities to add on a great deal of extra parts to be detached and exploded off through the damage scripts later on. The possibilities are limitless.
In this recipe, we will show you how to build a new script for CryENGINE 3 to recognize your car model as a vehicle entity. For this recipe, you must have some basic knowledge in XML formatting.
Open DefaultVehicle.xml in the XML editor of your choice (Notepad, Notepad++, UltraEdit, and so on). This XML will be used as the basic template to construct our new vehicle XML.
DefaultVehicle.xml is found at the following location: MyGameFolderScriptsEntitiesVehiclesImplementationsXml.
Open the MyVehicle.max scene made from the previous recipe to use as a reference for the parts section within this recipe.
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account at http://www.PacktPub.com. If you purchased this book elsewhere, you can visit http://www.PacktPub.com/support and register to have the files e-mailed directly to you.
<Vehicle name="MyVehicle" actionMap="landvehicle">
<Simulation maxTimeStep="0.02" minEnergy="0.002" maxLoggedCollisions="2"/>
For now, we will skip the Damages and Components cells as we will address them in a different recipe.
<Part name="body" class="Animated" mass="100" component="Hull">
<Parts>
</Parts>
<Animated filename="objects/vehicles/MyVehicle/MyVehicle.cga"
filenameDestroyed="objects/vehicles/HMMWV/HMMWV_damaged.cga"/>
</Part>
<Parts>
<Part name="wheel1" class="SubPartWheel" component="wheel_1" mass="80">
<SubPartWheel axle="0" density="0" damping="-0.7" driving="1" lenMax="0.4"
maxFriction="1" minFriction="1" slipFrictionMod="0.3" stiffness="0" suspLength="0.25" rimRadius="0.3" torqueScale="1.1"/>
</Part>
</Parts>
<Part name="massBox" class="MassBox" mass="1500" position="0,0,1."
disablePhysics="0" disableCollision="0" isHidden="0">
<MassBox size="1.25,2,1" drivingOffset="-0.7"/>
</Part>
<Parts>
<Part name="body" class="Animated" mass="100" component="Hull">
<Parts>
<Part name="wheel1" class="SubPartWheel" component="wheel_1" mass="80">
<SubPartWheel axle="0" density="0" damping="-0.7" driving="1" lenMax="0.4"
maxFriction="1" minFriction="1" slipFrictionMod="0.3" stiffness="0" suspLength="0.25"
rimRadius="0.3" torqueScale="1.1"/>
</Part>
<Part name="wheel2" class="SubPartWheel" component="wheel_2" mass="80">
<SubPartWheel axle="0" density="0" damping="-0.7" driving="1" lenMax="0.4"
maxFriction="1" minFriction="1" slipFrictionMod="0.3" stiffness="0" suspLength="0.25"
rimRadius="0.3" torqueScale="1.1"/>
</Part>
<Part name="wheel3" class="SubPartWheel" component="wheel_3" mass="80">
<SubPartWheel axle="1" density="0" damping="-0.7" driving="1" lenMax="0.4"
maxFriction="1" minFriction="1" slipFrictionMod="0.3" stiffness="0" suspLength="0.25"
rimRadius="0.3" torqueScale="1.1"/>
</Part>
<Part name="wheel4" class="SubPartWheel" component="wheel_4" mass="80">
<SubPartWheel axle="1" density="0" damping="-0.7" driving="1" lenMax="0.4"
maxFriction="1" minFriction="1" slipFrictionMod="0.3" stiffness="0" suspLength="0.25"
rimRadius="0.3" torqueScale="1.1"/>
</Part>
</Parts>
<Animated filename="objects/vehicles/MyVehicle/MyVehicle.cga"
filenameDestroyed="objects/vehicles/HMMWV/HMMWV_damaged.cga"/>
</Part>
<Part name="massBox" class="MassBox" mass="1500" position="0,0,1."
disablePhysics="0" disableCollision="0" isHidden="0">
<MassBox size="1.25,2,1" drivingOffset="-0.7"/>
</Part>
</Parts>
Finally, you will need to implement the MovementParams needed, so that the XML can access a particular movement behavior from the code that will propel your vehicle. To get started right away, we have provided an example of the ArcadeWheeled parameters, which we can copy over to MyVehicle:
<MovementParams>
<ArcadeWheeled>
<Steering steerSpeed="45" steerSpeedMin="80" steerSpeedScale="1" steerSpeedScaleMin="1"
kvSteerMax="26" v0SteerMax="40" steerRelaxation="130" vMaxSteerMax="12"/>
<Handling>
<RPM rpmRelaxSpeed="2" rpmInterpSpeed="4" rpmGearShiftSpeed="2"/>
<Power acceleration="8" decceleration="0.1" topSpeed="32" reverseSpeed="5" pedalLimitMax="0.30000001"/>
<WheelSpin grip1="5.75" grip2="6" gripRecoverSpeed="2" accelMultiplier1="1.2" accelMultiplier2="0.5"/>
<HandBrake decceleration="15" deccelerationPowerLock="1" lockBack="1" lockFront="0"
frontFrictionScale="1.1" backFrictionScale="0.1" angCorrectionScale="5" latCorrectionScale="1" isBreakingOnIdle="1"/>
<SpeedReduction reductionAmount="0" reductionRate="0.1"/>
<Friction back="10" front="6" offset="-0.2"/>
<Correction lateralSpring="2" angSpring="10"/>
<Compression frictionBoost="0" frictionBoostHandBrake="4"/>
</Handling>
<WheeledLegacy damping="0.11" engineIdleRPM="500" engineMaxRPM="5000" engineMinRPM="100"
stabilizer="0.5" maxTimeStep="0.02" minEnergy="0.012" suspDampingMin="0" suspDampingMax="0"
suspDampingMaxSpeed="3"/>
<AirDamp dampAngle="0.001,0.001,0.001" dampAngVel="0.001,1,0"/>
<Eject maxTippingAngle="110" timer="0.3 "/>
<SoundParams engineSoundPosition="engineSmokeOut" runSoundDelay="0" roadBumpMinSusp="10"
roadBumpMinSpeed="6" roadBumpIntensity="0.3" maxSlipSpeed="11"/>
</ArcadeWheeled>
</MovementParams>
After saving your XML, open the Sandbox Editor and place down from the Entities types: VehiclesMyVehicle. You should now be able to enter this vehicle (get close to it and press the F key) and drive around (W = accelerate, S = brake/reverse, A = turn left, D = turn right)!
The parts defined here in the XML are usually an exact match to the Max scene that the vehicle is created in. As long as the naming of the parts and the name of the subobjects within Max are the same, the vehicle structure should work.
The parts in the XML can themselves be broken down into their own properties:
The def_vehicle.xml file found in MyGameFolderScriptsEntitiesVehicles, holds all the property's definitions that can be utilized in the XML of the vehicles. After following the recipes found in this article, you may want to review def_vehicle.xml for further more advanced properties that you can add to your vehicles.