Game Development Community

wheeledVehicle - resetting the wheels after keypress?

by Stefan Beffy Moises · in Torque Game Engine · 06/23/2002 (2:33 pm) · 13 replies

Hellas!
Did anybody implement some code to reset the wheels after the "left" or "right" key was pressed (if you use the keyboard for steering)?
At the moment, $mvYawRightSpeed/$mvYawLeftSpeed are constantly updated and therefore the yaw/steer angle is constantly changed, so the wheels only move if as long as you press the key, which makes steering very difficult - would be much easier if the front wheels were switching back into their middle position immeadeately after you release the key...
Anybody tried this yet? :-)

#1
06/27/2002 (10:43 am)
Anyone?
#2
06/27/2002 (12:10 pm)
Quote:
Update wheel steering and suspension threads.
These animations are purely cosmetic and this method is only invoked
on the client
Hm, so I guess only updating the animations won't work...
e.g. setting the wheel positions like this:
Wheel* wend = &mWheel[mDataBlock->wheelCount];
   for (Wheel* wheel = mWheel; wheel < wend; wheel++) {
      mShapeInstance->setPos(wheel->springThread,0.5);
   }
Or will it? Man, this wheeled vehicle code is a tough one...
I'll keep examining it.... later!
#3
06/27/2002 (1:40 pm)
Nevermind (doesn't seem anybody did, though, hehe...) - got it working now...
#4
06/27/2002 (1:52 pm)
Sorry I didn't catch this thread earlier, I did a simple hack to do just that. In vehicles.cc:
// Steering
   if (move != &NullMove)
   {
	   if(move->yaw ){ 
	    F32 y = move->yaw;
		mSteering.x = mClampF(mSteering.x + y,-mDataBlock->maxSteeringAngle,
                            mDataBlock->maxSteeringAngle);
		F32 p = move->pitch;
		mSteering.y = mClampF(mSteering.y + p,-mDataBlock->maxSteeringAngle,
                            mDataBlock->maxSteeringAngle);

		}
		else
		{
		mSteering.x = 0;
		mSteering.y = 0;      
		 }
	   }
   else
   {
      mSteering.x = 0;
      mSteering.y = 0;      
   }

Also take a look at this thread here
#5
06/27/2002 (2:08 pm)
Hey Kevin, thanks a lot!! Interesting thread - if only this forum had a fulltext search... you never find these things if there isn't a very good descriptive title... :-(
As for your "hack" - works great for the keyboard, the only problem is that it affects the "mouse steering", too... which makes it impossible to use the mouse for driving... (at least for me)
maybe you want to try my solution which is a custom function in wheeledVehicle.cc- and then you can map it only to the keyboard ... let me know if you need it!
Thanks again for your help!!
#6
06/27/2002 (2:31 pm)
Btw., what is mSteering.y doing?
Isn't steering supposed to be on one axis only (mSteering.x) - anyhow, I'm only resetting mSteering.x and it seems to work....
#7
06/27/2002 (2:35 pm)
Yeah it pretty much makes the mouse useless for steering. I'd definitely like to check out your solution if you wouldn't mind, chances are it's much better... I couldn't agree more on the search function, it would save a lot of time and hassle if you could search a post itself.
#8
06/27/2002 (2:43 pm)
I'm not too sure what mSteering.y is doing, I think it may be for flying vehicles, but I haven't tried to do anything with those yet... I was just being on the safe side.
#9
06/27/2002 (3:34 pm)
Okay, so here is my little hack... ;-)
I wrote a little function in wheeledVehicle.cc setting the mSteering variable and exposed it to the scripting engine:
void WheeledVehicle::resetWheels()
{
	if(mSteering.x > 0.000000)
	{
		while(mSteering.x>0)
		{
			mSteering.x = mClampF(mSteering.x - 0.00001,-mDataBlock->maxSteeringAngle,
                            mDataBlock->maxSteeringAngle);
		}
	}
	else if(mSteering.x < 0.0000000)
	{
		while(mSteering.x<0)
		{
			mSteering.x = mClampF(mSteering.x + 0.00001,-mDataBlock->maxSteeringAngle,
                            mDataBlock->maxSteeringAngle);
		}
	}
}

ConsoleMethod( WheeledVehicle, resetWheels, void, 2, 2, "wv.resetWheels();" ) {
   WheeledVehicle *wv = static_cast<WheeledVehicle*>( object );
   wv->resetWheels();
}
I tried to add some delay with the "mSteering.x + 0.00001" stuff, but it doesn't really make a difference... so the function could also look like this, I guess:
void WheeledVehicle::resetWheels()
{
   mSteering.x = 0;
}
Well, that's pretty basic then... ;-)

Then, in game.cs I'm spawning a vehicle for every client:
$hoverVehicle = new WheeledVehicle() {
         dataBlock = "Ferrari";
      };
      $hoverVehicle.setTransform(pickSpawnPoint(2));
      $hoverVehicle.disableMove = "0";
      $hoverVehicle.mountable = "1";
      MissionCleanup.add($hoverVehicle);
Now I can access the global $hoverVehicle from a function in ferrari.cs (aka car.cs):
function resetWheels(%val){
   if(%val)
   {
      // only wait for keyrelease
   }
   else
   {
      $hoverVehicle.resetWheels();
   }
}
which is resetting the wheels on key-release...
So now, in default.bind.cs, I've copied the turnLeft and turnRight functions to
function steerLeft( %val )
{
      $mvYawRightSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0;
      resetWheels();
}
function steerRight( %val )
{
      $mvYawLeftSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0;
      resetWheels();
}
and added calls to the resetWheels function ...
And for my car, I've got a custom ActionMap which looks like this:
new ActionMap(CarDriveMap);
CarDriveMap.bind(keyboard, "right", steerRight);
CarDriveMap.bind(keyboard, "left", steerLeft);
CarDriveMap.bind(keyboard, "up", moveForward);
CarDriveMap.bind(keyboard, "down", movebackward);
CarDriveMap.bind(keyboard, "q", applyBrake);
CarDriveMap.bind(keyboard, "+", increaseCamDist);
CarDriveMap.bind(keyboard, "-", decreaseCamDist);
CarDriveMap.bind(keyboard, ".", increaseCamOffset);
CarDriveMap.bind(keyboard, ",", decreaseCamOffset);
CarDriveMap.bind(keyboard, "h", playHorn);

This way I can use the normal turnLeft/-Right functions while steering with the mouse and use my custom functions with wheel-reset with for keyboard steering...
bad hack, I guess, but it works...
Hope you can use it somehow!
#10
07/03/2002 (1:36 pm)
Hm, but the global $hoverVehicle var seems to be a problem in Multiplayer sessions, it seems to be global for ALL the clients (and pointing to the same vehicle?), so it looked like the function reset the wheels for different clients every once in a while... depending who was in his vehicle first?
Anyhow, it was quite strange from time to time...

So is there a way to get the actual vehicle and or player while steering (e.g. in default.bind.cs :
function turnLeft( %val )
{
   $mvYawRightSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0;
}
But there is no player/vehicle reference available it seems, so how do I get one which I then can use to reset the correct vehicles' wheels? In other words, how do I know *who* actually presses the keys to turn left or right and which vehicle is mounted on him without using global vars somewhere? Or would it help to set these globals in a client side script? Thanks for any MP insights... :-P
#11
07/06/2002 (12:18 am)
*Bumpidibump*
Can't get this to work in Multiplayer...
there *has to* be a way to access the current client who is steering, braking, etc. (and his mounted vehicle - that shouldn't be the problem, I can save it as a member variable of each client) within the steering etc. functions...
What I'm doing at the moment is storing each client in game.cs, GameConnection::createPlayer() like this:
...
   %player = new Player() {
   dataBlock = $mainPlayerDatablock;
   client = %this;
   };
   commandToClient(%this, 'StoreClient', %this);
   commandToClient(%this, 'InitQuickInventory',%player);
...
StoreClient is a CLIENT-side function in "client.cs"
function clientCmdStoreClient(%client)
{
   $me = %client;
   echo("Client stored:" SPC $me);

}
and then, during the game, I use the $me var and was hoping it holds a reference to himself *for every client*...
function resetWheels(%val)
{
   ...
   $me.currentMountedVehicle.resetWheels();
}
but it doesn't work...(although echo("Client stored:" SPC $me); indicated that the IDs stored ARE different) all the functions using the $me var are ONLY working for the player hosting the game, all the other clients seem either to not be able to access it OR they get the wrong reference (to the hosting player??)...

so how do I get the client actually performing an action like steering *while* he is performing it?? Aren't there "client specific global vars"?

if I have a function in default.bind.cs, like
function turnLeft( %val )
{
   $mvYawRightSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0;
}
how do I get the current client there???
Thanks for any help on this...!!
#12
07/07/2002 (7:29 am)
I'm going nuts!! :-/
Nothing works in Multiplayer...
I thought "localClientConnection" could solve my problems, but e.g. "localClientConnection.player.getTransform()" doesn't return anything (besides an error) in Multiplayer - in Singleplayer it returns the "%client" as I expected...
so in Multiplayer e.g.
localClientConnection.currentMountedVehicle.resetWheels();
still doesn't work...
doesn't anybody know how to access the individual clients in Multiplayer???
#13
07/07/2002 (11:42 am)
Okay, fixed it!
I had to go through a commandToServer function to get the steering to work:
// client/ui/ferrariGui.cs

function resetWheels(%val)
{
   if(%val)
   {
      // only wait for keyrelease
   }
   else
   {
      commandToServer('ResetWheels');
   }
}


// server/scripts/commands.cs

function serverCmdResetWheels(%client)
{
   %client.currentMountedVehicle.resetWheels();
}
The currentMountedVehicle is set in
player.cs:
function Armor::onCollision(%this,%obj,%col,%vec,%speed)
{
   //echo("Classname: " @ %this.className);
   //echo("mountable: " @ %col.mountable);
   //echo("state: " @ %obj.getState());
   //echo("mountVehicle: " @ %obj.mountVehicle);

   if (%obj.getState() $= "Dead")
      return;

   %client = %obj.client;

   // Try and pickup all items
   if (%col.getClassName() $= "Item")
   {
      %obj.pickup(%col);
      //commandToServer('InitQuickInventory');
   }
   else
   {
       %this = %col.getDataBlock();
       // Mount vehicles
       if ((%this.className $= WheeledVehicleData 
|| %this.className $= WaterCraftData 
|| %this.className $= FlyingVehicleData  
|| %this.className $= TurretBodyData) && %obj.mountVehicle 
&& %obj.getState() $= "Move" && %col.mountable) {
         // Only mount drivers for now.
         %node = 0;
         if(%col.getDatablock().getName() $= "Ferrari")
         {
            %node = 2;
         }
         %col.mountable=false;// Set Vehicle Unmountable
         %col.mountObject(%obj,%node);
         %obj.mVehicle = %col;

         %player = %client.player;

         %col.currentDriver = %client;
         %client.currentMountedVehicle = %col;
         CommandToClient(%client, 'setFerrariGui');
      }
   }
}