3D Game Programming All in One (Course Technology PTR Game Development Series)
Vehicles are obvious sound sources. An idling engine, squealing tires, whirring propellers—the kind of vehicle dictates the needs. Torque has several defined vehicle types, but we'll just look at the wheeled vehicle and add some sound effects to the runabout.
To start, you will need to record sound effects for the following:
-
engine idle
-
acceleration
-
wheel impact
-
wheel squeal
-
soft crash
-
hard crash
In lieu of creating your own, feel free to use the sounds that I have provided at C:\3DGPAi1\RESOURCES\CH20\. Deposit the files into C:\koob\control\data\sound\.
Next, copy the car definition module, C:\3DGPAi1\RESOURCES\CH20\CAR.CS, to C:\koob\control\data\server\vehicles. If the directory doesn't exist, create it.
Then copy your runabout model and all its artwork into C:\koob\control\data\models\vehicles. Again, if the directory doesn't exist, create it. Make sure your runabout is named "
Now open the file C:\koob\control\server\server.cs and find the line that reads as follows:
$Game::StartTime = 0;
Just beyond that line is a block of exec() statements. Insert the following at the top or bottom of that block of statements:
Exec("./vehicles/car.cs");
This tells the engine to load your car definition file.
And finally, open the file you copied earlier, C:\koob\control\server\vehicles\car.cs, and add the following lines to the end:
datablock AudioProfile(CarSoftImpactSound) { filename = "~/data/sound/vcrunch.wav"; description = AudioClose3d; preload = true; }; datablock AudioProfile(CarHardImpactSound) { filename = "~/data/sound/vcrash.wav"; description = AudioClose3d; preload = true; }; datablock AudioProfile(CarWheelImpactSound) { filename = "~/data/sound/impact.wav"; description = AudioClose3d; preload = true; }; datablock AudioProfile(CarThrustSound) { filename = "~/data/sound/caraccel.wav"; description = AudioDefaultLooping3d; preload = true; }; datablock AudioProfile(CarEngineSound) { filename = "~/data/sound/caridle.wav"; description = AudioClose3d; preload = true; }; datablock AudioProfile(CarSquealSound) { filename = "~/data/sound/squeal.wav"; description = AudioClose3d; preload = true; }; datablock WheeledVehicleData(DefaultCar) { category = "Vehicles"; className = "Car"; shapeFile = "~/data/models/vehicles/runabout.dts"; emap = true; maxDamage = 1.0; destroyedLevel = 0.5; maxSteeringAngle = 0.785; // Maximum steering angle tireEmitter = TireEmitter; // All the tires use the same dust emitter // 3rd person camera settings cameraRoll = true; // Roll the camera with the vehicle cameraMaxDist = 6; // Far distance from vehicle cameraOffset = 1.5; // Vertical offset from camera mount point cameraLag = 0.1; // Velocity lag of camera cameraDecay = 0.75; // Decay per sec. rate of velocity lag // Rigid Body mass = 200; massCenter = "0 -0.5 0"; // Center of mass for rigid body massBox = "0 0 0"; // Size of box used for moment of inertia, // if zero it defaults to object bounding box drag = 0.6; // Drag coefficient bodyFriction = 0.6; bodyRestitution = 0.4; minImpactSpeed = 5; // Impacts over this invoke the script callback softImpactSpeed = 5; // Play SoftImpact Sound hardImpactSpeed = 15; // Play HardImpact Sound integration = 4; // Physics integration: TickSec/Rate collisionTol = 0.1; // Collision distance tolerance contactTol = 0.1; // Contact velocity tolerance // Engine engineTorque = 4000; // Engine power engineBrake = 600; // Braking when throttle is 0 brakeTorque = 8000; // When brakes are applied maxWheelSpeed = 30; // Engine scale by current speed / max speed // Energy maxEnergy = 100; jetForce = 3000; minJetEnergy = 30; jetEnergyDrain = 2; // Sounds engineSound = CarEngineSound; jetSound = CarThrustSound; squealSound = CarSquealSound; softImpactSound = CarSoftImpactSound; hardImpactSound = CarHardImpactSound; wheelImpactSound = CarWheelImpactSound; };
As you've seen in earlier sections, we start out with a gaggle of AudioProfiles that define each of our sounds.
After that comes the vehicle datablock. Most of the properties are explained in the code commentary or are self-explanatory. The ones that we are interested in the most are at the end.
The engineSound property is the sound the vehicle makes while idling. As long as the vehicle is running, it will make this noise.
The jetSound property is the one used when the vehicle accelerates. The name is a holdover from the Tribes 2 game engine in the early Torque days.
The squealSound property is the sound emitted by the tires when the vehicle is manhandled around a corner, causing the tires to slip.
The two impact sound properties, softImpactSound and hardImpactSound, are used when the vehicle collides with objects at different speeds, as defined by the softImpactSpeed and hardImpactSpeed properties earlier in the datablock.
Finally, the wheelImpactSound is the sound emitted when the wheels hit something at greater than the minimum impact speed, defined by minImpactSpeed earlier in the datablock.
Now we have to make some changes to our player's behavior. What we want is to have the player get in the car when he goes up to it.
Open the file C:\koob\control\server\players\player.cs and locate this line:
%this = %col.getDataBlock();
and add the following after it:
if ( %this.className $= "Car" ) { if (%this.salvageFlag) %this.salvageFlag=0; %node = 0; // Find next available seat %col.mountObject(%obj,%node); %obj.mVehicle = %col; } else {
Then scroll down until you find this line:
%col.applyImpulse(%pos,%vec);
and add a closing brace ("}") after that line.
Next, add the following code to the end of the file:
function HumanMaleAvatar::onMount(%this,%obj,%vehicle,%node) { %obj.setTransform("0 0 0 0 0 1 0"); %obj.setActionThread(%vehicle.getDatablock().mountPose[%node]); if (%node == 0) { %obj.setControlObject(%vehicle); %obj.lastWeapon = %obj.getMountedImage($WeaponSlot); %obj.unmountImage($WeaponSlot); %db = %vehicle.getDatablock(); } } function HumanMaleAvatar::onUnmount( %this, %obj, %vehicle, %node ) { %obj.mountImage(%obj.lastWeapon, $WeaponSlot); } function HumanMaleAvatar::doDismount(%this, %obj, %forced) { // This function is called by the game engine when the jump trigger // is true while mounted // Position above dismount point %pos = getWords(%obj.getTransform(), 0, 2); %oldPos = %pos; %vec[0] = " 1 1 1"; %vec[1] = " 1 1 1"; %vec[2] = " 1 1 -1"; %vec[3] = " 1 0 0"; %vec[4] = "-1 0 0"; %impulseVec = "0 0 0"; %vec[0] = MatrixMulVector( %obj.getTransform(), %vec[0]); // Make sure the point is valid %pos = "0 0 0"; %numAttempts = 5; %success = -1; for (%i = 0; %i < %numAttempts; %i++) { %pos = VectorAdd(%oldPos, VectorScale(%vec[%i], 3)); if (%obj.checkDismountPoint(%oldPos, %pos)) { %success = %i; %impulseVec = %vec[%i]; break; } } if (%forced && %success == -1) %pos = %oldPos; %obj.unmount(); %obj.setControlObject(%obj); %obj.mountVehicle = false; // Position above dismount point %obj.setTransform(%pos); %obj.applyImpulse(%pos, VectorScale(%impulseVec, %obj.getDataBlock().mass)); }
This code allows us to get in (mount) the car and then get out (dismount). There's nothing about the sound in there, but it is convenient to have this ability.
Now use the same procedures with the World Editor as with the Tommy gun to insert the car into the game world. You will find the car in the Tree view under Shapes, Vehicles. Remember to tug the model up out of the ground if it's embedded in the ground—but don't tug it too hard!
Run up to the car, and you will automatically go inside and be seated. Use the normal forward movement key (Up Arrow) to accelerate, and the mouse to steer left and right. Have at it!
Категории