Game Development Community

Adding Multiple Recoiling Animations for a single Player Model

by Michael Dillon · 09/20/2004 (12:51 am) · 5 comments

This is a quick description on how to have multiple character animations for firing weapons. For example, having an animation of the character firing a gun, then a different animation for that character throwing a grenade.

How to do it:

Within the script for the model, you will have to label the dsq's for each animation with light_recoil, medium_recoil, and heavy_recoil.

datablock TsshapeConstructor(PlayerDTS)
{
       baseShape = "./player.dts";
       sequence0 = "./player_ROOT.dsq root";
       sequence1 = "./player_ATTACK1.dsq light_recoil";
       sequence2 = "./player_ATTACK2.dsq medium_recoil";
       sequence3 = "./player_ATTACK3.dsq heavy_recoil";
}

That part is easy enough. Now open up the [bold]player.cc[/b] in the engine\game folder and scroll down (or Crtl+F) to void Player::onImageRecoil. The first thing we will do here is change the function parameters. Change the parameters to this:

void Player::onImageRecoil(U32 imageSlot, ShapeBaseImageData::StateData::RecoilState state)

Don't forget to update the prototype for this function as well.

Next, this function have a variable called mRecoilThread that is set to the last recoil that was loaded. So if you loaded a light and a medium recoil, this will be set to medium. However, this does not change that variable to the light_recoil ever. Lets change that. Replace that if statement with the following:

int newstate = (int)(state - 1);  // converts from ShapeBaseImageData::StateData::RecoilState to PlayerData::Recoil

if(newstate >= PlayerData::LightRecoil && newstate <= PlayerData::HeavyRecoil) {
      if(mDataBlock->recoilSequence[newstate] != 1) {
            if(mRecoilThread) {
                  mShapeInstance->destroyThread(mRecoilThread);
                  mRecoilThread = mShapeInstance->addThread();
                  mShapeInstance->setSequence(mRecoilThread, mDataBlock->recoilSequence[newstate], 0);
                  mShapeInstance->setPos(mRecoilThread,0);
                  mShapeInstance->setTimeScale(mRecoilThread,1);
           }
      }
}

There we go. That allows Torque to change from one recoil to another. Now just to call them in script. In the script file for your weapon (we will use crossbow.cs for example) go to ShapeBaseImageData(CrossbowImage) and scroll down to the line:
stateRecoil[3] = LightRecoil;
Here, type LightRecoil, MediumRecoil, or HeavyRecoil, depending on which animation you want to play when the player fires this weapon.


Closing
Huge thanks to Robert Brower for his help in getting this to work. Major props to him.

About the author

Recent Blogs


#1
03/16/2005 (3:18 pm)
cheers for the resource, got it working easy
#2
10/24/2006 (11:19 pm)
that looks good. does it look smooth though from switching from idle to shootin with a different weapon.
also what about different running/idle animations for when having different weapons equiped. for instance the animation of the pistol only requires one hand and looks weird on the default animation which is for a larger weapon.
#3
11/13/2009 (12:58 am)
I realize this is an old thread but hopefully someone knows what

"Don't forget to update the prototype for this function as well."

means...

Also, I set this up and it seems to work but sometimes my AI just stands and continues to throw his grenade without the animation and then he doesn't even play the run animation unless I blast him and kind of 'restart' him...
#4
11/14/2009 (7:24 pm)
Since no one is at all likely to read this, I am going to attempt to explain what
Quote:"Don't forget to update the prototype for this function as well."
means. Please take this with a grain of salt, because I may be completely wrong. Ok, the function in question is:

void Player::onImageRecoil(U32 imageSlot, ShapeBaseImageData::StateData::RecoilState state)

See how the function above has both the variable type (U32) and a variable name ( imageslot)?

Somewhere, I would imagine in player.h file, (if that exists, I didn't look) you will see the function prototype for this, which should like almost like the above, but without the specific variable names, only the variable types, ie:

void Player::onImageRecoil(U32 , shapeBaseImageData::StateData::RecoilState )

What the author is saying is that this prototype function also has to be update to match the updated function.

Since I have not looked at the code, I do not know what the OLD function prototype looks like, but my guess is that the NEW one should look like this:

void Player::onImageRecoil(U32 , shapeBaseImageData::StateData::RecoilState )

Well, I hope this helps more than it hurts, good luck!
#5
11/14/2009 (10:41 pm)
hmmm, well I found and did that update in player.h...basically just added the word state at the end. But the AI slides across the ground half the time and then sometimes doesn't play the full animation...so...I completely undid all of the changes and just left the changes to myweapon.cs and mymonster.cs to see if he would still play my throw animation when medium_recoil was called and he did...so either I did something wrong or all of the editing of player.cpp and player.h seemed to be of no value at all. (I compiled each time)
I'm using T3D though so maybe that's the difference.
I don't know...but, the animation isn't acceptable overall using this method, for me anyway...in T3D.

Still looking for the answer!