Game Development Community

dev|Pro Game Development Curriculum

Swimming in one step -- standard FPS swimming physics

by Henry Todd · 11/13/2006 (4:38 pm) · 30 comments

*Updated 5/22/09: This code is already included and improved upon in stock T3D Beta1+

*Updated 1/26/07 to fix typo in code: missing ')'*
*Updated 11/6/07 to clarify a confusing element and add explaination.*
*Updated 11/12/07 to upgrade vector calculations, add moveUp/moveDown support.*

While there is one swimming resource available (Swim/Crawl/Crouch resource, it includes extra code for move states (crouch, etc.) and uses a slightly awkward (as admitted by the author) swim vector calculation routine.

This resource is intended to provide FPS-style swimming physics in a simple patch which can be done in about 30 seconds. If you also want crouching and crawling, check out the link above.

What it does: Swim in any direction you can look, using existing runForce calculations. One file change.

What it does not: Animations not included; there are many existing tutorials on adding new animations to your player object.

With that said, open player.cpp (or .cc for older versions) and go to the function:

void Player::updateMove(const Move* move)

Find the following if-else in updateMove:

if (runSurface) {
...<All the code for running (Don't delete this stuff!)>...
}
else
   mContactTimer++;

..and make it look like this (new code in bold):

if (runSurface) {
...<All the code for running (Don't delete this stuff!)>...
}
[b]
else if (inLiquid)
{
   // get the head pitch and add it to the moveVec
   // This more accurate swim vector calc comes from Matt Fairfax
   MatrixF xRot, zRot;
   xRot.set(EulerF(mHead.x, 0, 0));
   zRot.set(EulerF(0, 0, mRot.z));
   MatrixF rot;
   rot.mul(zRot, xRot);
   rot.getColumn(0,&moveVec);

   moveVec *= move->x;
   VectorF tv;
   rot.getColumn(1,&tv);
   moveVec += tv * move->y;
   rot.getColumn(2,&tv);
   moveVec += tv * move->z;

   // Force a 0 move if there is no energy, and only drain
   // move energy if we're moving.
   VectorF pv;
   if (mEnergy >= mDataBlock->minRunEnergy) {
      if (moveSpeed)
         mEnergy -= mDataBlock->runEnergyDrain;
      pv = moveVec;
   }
   else
      pv.set(0,0,0);

  F32 pvl = pv.len();

   // Convert to acceleration
   if (pvl)
      pv *= moveSpeed / pvl;
   VectorF runAcc = pv - mVelocity;
   F32 runSpeed = runAcc.len();

   // Clamp acceleration, player also accelerates faster when
   // in his hard landing recover state.
   F32 maxAcc = (mDataBlock->runForce / mMass) * TickSec;
   if (mState == RecoverState)
      maxAcc *= mDataBlock->recoverRunForceScale;
   if (runSpeed > maxAcc)
      runAcc *= maxAcc / runSpeed;
   acc += runAcc;

   mContactTimer++;
}
[/b]
else
   mContactTimer++;

Compile and jump in some water. You should be able to swim, assuming your player is not too heavy or dense. You may notice that you can still walk on the bottom of the ocean if you make contact with it.

Density: If your player has a higher density than the water, he will sink and swim very slowly. A lower density will cause the player to rise and accelerate more quickly. Equal density will make swimming feel like flying. I recommend the player's density be just slightly higher than the water's, for the sake of realism.

Waves: The waves in TGE's waterblock don't exist on the server, so they won't be part of the swimming physics.

For those interested in what this actually does, you're changing the if-else chain that usually does:
"If we're on the ground, use the running code. Else, don't do anything except count, because we're in the air."
Into:
"If we're on the ground, use the running code. Else, if we're underwater, use the swimming code. Else, we're in the air, just count."

Upgraded on 11/12/07 to use a more accurate, slightly more math-intensive swim vector. The old method worked fine, but this version is "correct" in comparison to other FPS swimming models. It also now supports move up and move down (move->z).
Page«First 1 2 Next»
#21
12/27/2007 (7:09 am)
How do you add swimming animations to this (swimming idle, left, right, back, and forward)?
#22
04/30/2008 (12:33 am)
Does not work in TGEA 1.7.0 I hear.
#23
06/14/2008 (3:57 pm)
Long time ago, but I did get animations working with this, btw.

@Bryan
I would think that it works. I don't own TGEA, but unless the player class got a dramatic make-over, than the code should be about the same, and if it did, the code isn't to complex.
#24
06/27/2008 (7:00 am)
THIS IS AWESOME ....quick to implement and works really well. You have to use the mouse to "swim up" or "swim down".... but as long as player understand that I think it should be OK

I may way to add something to use key bindings to move player up and down while swimming.


OK.....SO I AM ALSO INTERESTED IN LEARNING HOW TO ADD SWIMMING ANIMATIONS TO THIS. ANYONE KNOW HOW TO DO THIS? I have already completed the swimming animation for my character in 3ds max....i just need to find out how to make it work with this new code. Thanks.
#25
06/29/2008 (6:33 am)
Hey, I got swimming animations to work with this.

For anyone interested in a clue how to do this (adding the actual swimming animations) , I found this thread helpful:

http://www.garagegames.com/mg/forums/result.thread.php?qt=33789
#26
12/04/2008 (10:17 am)
nice one! works a treat in 1.7.1, added this in addition to the "swim, crouch, crawl" resource. now they all work. lovely!
#27
12/19/2008 (7:35 pm)
Doesn't work in a clean build of TGE 1.5.2, atleast not for me.
#28
12/19/2008 (7:36 pm)
Perhaps someone who got it to work should paste the section of code here?
#29
07/21/2009 (10:01 pm)
@Okashira:

What's happening for you? Nothing? The code as it is posted in the resource works for me, just rebuilt it in TGE 1.5.2

Let us know what is or is not happening in your build.

My problem is that I can't get the animations that go with it to work anymore in AFX. It worked for me in stock 1.5.2 but in AFX 1.1 (afx in 1.5.2), I "swim" but not with my animations.

I had referenced this thread:
http://www.garagegames.com/mg/forums/result.thread.php?qt=33789

which works for me for stock torque but not AFX. So there's some extra stuff I have to do in AFX to get the animations working methinks.

#30
07/21/2009 (10:46 pm)
Ok here I am finding my own answers to my own questions.

I had forgotten that the last time I got the animations working with this, I had to do:

if (inLiquid){
action = PlayerData::SwimAnim;
}

right at the end of the

pickActionAnimation() in player.cc

this thread is where that was discussed:
http://www.garagegames.com/community/forums/viewthread/76905

My swimming animations do work now with the swimming but not all the time. If I hit the bottom of the lake, I still end up running, which doesn't look right, but even the resource said this will happen. There must be a way around this, though.

Page«First 1 2 Next»