Game Development Community

Vehicle engine sound problems and questions

by Ronald J Nelson · in Torque Game Engine · 04/01/2007 (3:57 am) · 4 replies

First, let me say that I am using this resource which I have been modifying extensively with several updates to the code.

www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=7903

I am working on an ignition system to allow turning on and off the vehicle's engine. So far most of it is working quite well except for a strange problem I am getting. Now the main portion of my code update for this was to add an additional condition to different parts of the code to stop engine rpm, torque and the sound and reenable it based off of a function. The following is the beginnings of my function.

void WheeledVehicle::startStopEngine()
{
   //Need to switch ignition
	if(ignitionOn)
	{
		//If engine is running, shut it off
		ignitionOn = false;
		setGear(0);
		if (mEngineSound) 
		{
            alxStop(mEngineSound);
            mEngineSound = 0;
		}
	}
	else
	{
		//If engine is off start it
		if (mDataBlock->sound[WheeledVehicleData::EngineSound])
		{
            mEngineSound = alxPlay(mDataBlock->sound[WheeledVehicleData::EngineSound], &getTransform());
		}
		ignitionOn = true;
		inPark = false;
		if(useAutomatic)
		{
			inNeutral = false;
			setGear(1);
		}
	}
}

Now the problem is that where ever I start the engine, the engine sound stays there and doesn't travel with the vehicle.

I am sure it is something fairly simple I have missed so I am hoping one of you can tell me my mistake.

Also, since I am going to add a starting sound as as well, how can I in code tell when a sound has finished playing so I can tell when to start the engine sound?

#1
04/01/2007 (3:10 pm)
Unless someone can contradict me, this is accomplished through the engine as opposed to scripting.

You're creating your sound at the position where the vehicle was residing when the engine was started, but there's nothing that updates that position. Doing this via scripting is tricky, at best.

I'd add an "engineOn" variable to the WheeledVehicle class in scripting. Find the places in the class where engine noise is updated and place an if (engineOn) { ... } block around it.

You'd probably want to extend this to the movement update code as well, since you probably don't want the vehicle to be able to receive new velocity inputs (other than gravity) with the engine off.
#2
04/01/2007 (7:25 pm)
@ Bryce - This is engine code. I figured out what is causing the problem, just not sure why.

As you can see I added this additional check to this section of code in WheeledVehicle::onNewDataBlock.

if (isGhost() && ignitionOn) 
   {
       // Start the engine
	   if (mDataBlock->sound[WheeledVehicleData::EngineSound])
	   {
		   mEngineSound = alxPlay(mDataBlock->sound[WheeledVehicleData::EngineSound], &getTransform());
	   }
   }

If I take out the check, it works fine. Funny thing is that if I use my function to start the engine while this code does not have the ignitionOn check, it adds an additional engine sound that is not attached to the car. However there is still the car's that was added by removing the check.

I am sure it has something to do with the fact that it is being added at the creation of the datablock but I cannot see why you can't just have the sound travel with the vehicle in my function.
#3
04/02/2007 (12:35 am)
OK I have to admit this one has me baffled. Why is it that the sound will only stay with the vehicle on the creation of a new datablock? Is there some other way to go about this?

It just seems odd to me that no one else has tried turning off and on the engine sound.
#4
04/25/2011 (6:12 am)
(EDIT)*************(EDIT)
Yeah it has been awhile lol...
This is for T3D Preview implementation
This is what happens when ya pull an all niter
and forget to look at the Date on a post *chuckle*
(EDIT)*************(EDIT)

Well, its been awhile since I posted, but I figured I'd give ya a quick boost for this one...

This connects to any vehicle based off of vehicle.cpp

Requires Engine Modifications:

vehicle.h
.....
   bool inLiquid;
   SFXSource* mWakeSound;

   //Mythic Added (near line:198)	
   bool mEngineOn;

   Point3F mCameraOffset; ///< 3rd person camera
......
   bool onAdd();
   void onRemove();

   //Mythic Added  (near line:276)
   void setEngineOn( bool valueB ) { mEngineOn = valueB; };
   bool isEngineOn() { return mEngineOn; };

   /// Interpolates between move ticks @see processTick
......

vehicle.cpp
.......
   mThrottle = 0;
   mJetting = false;

   //Mythic Added (near line:606)
   mEngineOn = false;

   mCameraOffset.set(0,0,0);
......

   stream->writeFlag(mJetting);
   
   //Mythic Added (near line:1562)
   stream->writeFlag(mEngineOn);

   // The rest of the data is part of the control object packet update.
......
   mJetting = stream->readFlag();

   //Mythic Added (near line:1595)
   mEngineOn = stream->readFlag();

   if (stream->readFlag())
      return;
.....
   //Added to end of File
DefineEngineMethod( Vehicle, setEngineOn, void, (bool state), ( false ),
   "Turns Engine Sounds on/off.n" )
{
   object->setEngineOn( state );
}

Now we connect this to the current base 3 vehicle types

Flyingvehicle.cpp (This one was simple)
void FlyingVehicle::advanceTime(F32 dt)
{
   Parent::advanceTime(dt);

	if( isEngineOn() )
	{
		updateEngineSound(1);
		updateJet(dt);
	}
}

WheeledVehicle.cpp (fairly simple)
// Update the sounds based on wheel slip and torque output
	if( isEngineOn() )
	{
		updateSquealSound(slipTotal / mDataBlock->wheelCount);
		updateEngineSound(sIdleEngineVolume + (1 - sIdleEngineVolume) * (1 - (torqueTotal / mDataBlock->wheelCount)));
		updateJetSound();
	}

   updateWheelThreads();

Then to connect it finally in script....
scripts/server/player.cs

in the functions onMount/unMount we disable/enable the sounds
this is a very simple implementation, (No Keys *grin*)

function Armor::onMount(...)
{
....
      %obj.unmountImage($WeaponSlot);

      %obj.setControlObject(%vehicle);
      //%obj.client.setObjectActiveImage(%vehicle, 2);
      %vehicle.setEngineOn(true);
   }
   else
   {
      if (%vehicle.getDataBlock().mountPose[%node] !$= "")
.....
}

function Armor::onUnmount(%this, %obj, %vehicle, %node)
{
   %obj.setActionThread("run", true, true);
   if (%node == 0)
   {
      %obj.mountImage(%obj.lastWeapon, $WeaponSlot);
      %obj.setControlObject("");
      %vehicle.setEngineOn(false);
   }
}

That should get ya started...
:)