[v3.6.1] Preventing aircraft "Sticking" using Torque Script

Scripts and code that enhance the gameplay functionality of the engine.
4 posts Page 1 of 1
WaxyChicken
Posts: 8
Joined: Wed Mar 04, 2015 9:27 pm
by WaxyChicken » Wed Mar 04, 2015 10:21 pm
In this version of Torque3D MIT (v3.6.1) there is still the problem of aircraft getting stuck in terrain or other objects.
such as when you land an aircraft at low speeds and it slowly drifts into a wall and "Gets Stuck".

These code tweaks will help to automatically "UNSTICK" your stuck aircraft.

using your editor add these dynamic values into your vehicle datablock:
lastColVec = 0 0 0 
lastColVecB = 1 1 1
unstickMeter = 0



in your scripts:

scripts / server / vehicle.cs

function VehicleData::onAdd(%this, %obj)
{
%obj.setRechargeRate(%this.rechargeRate);
%obj.setEnergyLevel(%this.MaxEnergy);
%obj.setRepairRate(0);

if (%obj.mountable || %obj.mountable $= "")
%this.isMountable(%obj, true);
else
%this.isMountable(%obj, false);

if (%this.nameTag !$= "")
%obj.setShapeName(%this.nameTag);

if (%obj.getClassName() $= "FlyingVehicle")
%this.CheckForStuck(%obj);
}

because it tends to occur with only flying vehicles, adding in
if (%obj.getClassName() == "FlyingVehcile")
will make it apply only to flying vehicles.
%this.CheckForStuck(%obj);
is the call that will start it's routine checking for getting stuck, and pushing the vehicle back when a sticky situation is detected.

these values are managed by the onCollision and onImapct functions:
function VehicleData::onCollision(%this, %obj, %sourceObject, %position, %len)
{
%tempPosition = %obj.getPosition();
if (%obj.lastColVec !$= %tempPosition)
{
%obj.lastColVecB = %obj.lastColVec;
%obj.lastColVec = %tempPosition;
}
}



function VehicleData::onImpact(%this, %obj, %sourceObject, %position, %len)
{
%tempPosition = %obj.getPosition();
if (%obj.lastColVec !$= %tempPosition)
{
%obj.lastColVecB = %obj.lastColVec;
%obj.lastColVec = %tempPosition;
}
}


during any contact with another object - collision or full impact speed - the position the the craft will now be stored in the datablock.
this will provide "Rewind" values. We will get to that later.

For now, add in the function that does the actual hard work:
function VehicleData::CheckForStuck(%this,%obj)
{
//Make sure this vehicle still exists. return if it doesn't.
if(!isObject(%obj) )
{
return;
}

%Vehiclepos = %obj.getPosition();
if (%Vehiclepos $= %obj.UnstickPosition)
{
// the vehicle is stuck!?!
// let it check a couple more times on our sticky meeter to make sure.
%obj.unstickMeter = %obj.unstickMeter + 1;
if (%obj.unstickMeter > 2)
{
// echo (" ============== ATTEMPTING TO UNSTICK! ---");
if (%obj.unstickMeter > 5)
{
// UNSTICK IS NOT WORKING!
// you may wish to add code to destroy the vehicle or kill the player at this point.
%obj.unstickMeter = 5;
}

// let's check our two history variables for a previous nearby collision
// and set vehicle back to that position.
// it will either bump lose quickly or "Shake" loose.
if (%vehiclepos $= %obj.lastColVec)
{
%newPosition = %obj.lastColVecB;
}
else
{
%newPosition = %obj.lastColVec;
}

// echo ("Unstick Attempt - change " @ %vehiclepos @ " to " @ %newPosition);
%obj.setTransform(%newPosition));
}
}
else
{
%obj.unstickMeter = 0;
%obj.unstickPosition = %VehiclePos;
}

if ( isObject(%obj) )
{
// decrease the 250 to a lower number for a faster response to sticking but more burden on the server / hosting client.
%this.schedule(250,CheckForStuck,%obj);
}
else
{
// at some point during this function the vehicle was removed or destroyed.
// echo("\c1 Vehicle::: DESTROYED!");
}
}


i find this working on aircraft datablocks with the following values:
bodyRestitution = 1
bodyFriction = 0.1
collisionTol = 1
contactTol = 1

this is intended only for vehicles that have a minimum speed > 0 (even if they are just wiggling in place)

this is not a "TRUE" solution or a perfect fix, but it does make getting stuck MUCH more rare and with
some tweaking you may get better results.
cybore
Posts: 16
Joined: Fri Feb 13, 2015 10:18 am
by cybore » Wed Mar 04, 2015 11:52 pm
Handy information. Thanks!
Gibby
Posts: 71
Joined: Wed Feb 11, 2015 2:40 pm
by Gibby » Thu Mar 05, 2015 4:53 pm
taming the collisions between vehicles and terrain in T3D can be a downward spiral. The same problems affect space, water, hover and vtol vehicles as well - adding this change to vehicle.cpp around line 1212 solves most of these issues:

Code: Select all


//----------------------------------------------------------------------------
/** Update the physics
*/

void Vehicle::updatePos(F32 dt)
{
   PROFILE_SCOPE( Vehicle_UpdatePos );

   Point3F origVelocity = mRigid.linVelocity;
 
   //-->>[HNG] Vehicles
   // Update internal forces acting on the body.
   mRigid.clearForces();
   updateForces(dt);
   if (!mRigid.atRest) 
      mRigid.integrate(dt);
   //<<--[HNG] Vehicles

   // Update collision information based on our current pos.
   bool collided = false;
   if (!mRigid.atRest) {
      collided = updateCollision(dt);

      // Now that all the forces have been processed, lets
      // see if we're at rest.  Basically, if the kinetic energy of
      // the vehicles is less than some percentage of the energy added
      // by gravity for a short period, we're considered at rest.
      // This should really be part of the rigid class...
      if (mCollisionList.getCount())
      {
         F32 k = mRigid.getKineticEnergy();
         F32 G = sVehicleGravity * dt;
         F32 Kg = 0.5 * mRigid.mass * G * G;
         if (k < sRestTol * Kg && ++restCount > sRestCount)
            mRigid.setAtRest();
      }
      else
         restCount = 0;
   }
   //-->>[HNG] Vehicles
   // Integrate forward
   //if (!mRigid.atRest)
   //   mRigid.integrate(dt);
   //<<--[HNG] Vehicles
   // Deal with client and server scripting, sounds, etc.

TorqueFan
Posts: 87
Joined: Thu Apr 30, 2015 5:35 am
by TorqueFan » Tue Jun 02, 2015 12:40 pm
Nice, this is useful. Thanks!
4 posts Page 1 of 1

Who is online

Users browsing this forum: No registered users and 1 guest