Working with pickActionAnimation()
by Erik Madison · 10/31/2005 (2:00 pm) · 6 comments
The current method of choosing your main action animation bases it's decision on the animations speed and the players velocity. While it works, and is possibly the more efficient method (I'm not a pro, I don't know), it's also extremely confusing to follow. And, personally, I've never managed to get my animation speeds nor ground transform changes to match the ingame velocity properly, which is how you would switch from a walk to a run.
Here's the current method:
And one more note; the sprinting bool is non-stock, and is just an extension of any of the multitude of player set agility, speed, etc. resources. In our case, the datablock maxspeed is set to a normal walk speed. Various factors will cause your player to exceed this, such as going downhill, or adding any form of speed multiplier. Even stock Torque will exceed your DB value in some cases.
Here's the current method:
for (i = 1; i < PlayerData::NumMoveActionAnims; i++) {
PlayerData::ActionAnimation &anim = mDataBlock->actionList[ i ];
if (anim.sequence != -1 && anim.speed) {
F32 d = mDot(vel, anim.dir);
if (d > curMax) {
curMax = d;
action = i;
forward = true;
} else {
// Special case, re-use slide left animation to slide right
if (i == PlayerData::SideLeftAnim && -d > curMax) {
curMax = -d;
action = i;
forward = false;
}
}
}
}And here's my version: Like I said, it may not be quite as efficient, but its a whole lot more readable, and thus allows me to insert and check for any conditions I wish.bool sprinting = vel.y > mDataBlock->maxForwardSpeed; // optional
if (!vel.len() || vel.len() < .01) { // anti twitch. If on a slope, they want to move
action = PlayerData::RootAnim; // just a little bit. Slope code here?
forward = false;
} else if (abs(vel.y) > abs(vel.x)) { // forward/back
if (sprinting && vel.y) {
action = PlayerData::RunForwardAnim;
forward = true;
//Con::errorf("SPRINT %f %f", vel.x, vel.y);
} else if (vel.y > 0.0) {
action = PlayerData::WalkForwardAnim;
forward = true;
//Con::errorf("WALK %f %f", vel.x, vel.y);
} else if (vel.y < 0.0) {
action = PlayerData::BackBackwardAnim;
forward = false;
//Con::errorf("BACK %f %f", vel.x, vel.y);
}
} else if (vel.x < 0.0) {
action = PlayerData::SideLeftAnim;
forward = false;
//Con::errorf("LEFT %f %f", vel.x, vel.y);
} else if (vel.x > 0.0) {
action = PlayerData::SideRightAnim;
forward = false;
//Con::errorf("RIGHT %f %f", vel.x, vel.y);
}
}
}A note about the anti twitch thingy; I noticed during testing that on a level ground, velocity was always 0. On even the slightest slope, there was always some velocity. Although the player never moved (small value negated by another force later on?), they would 'twitch' a bit. So for the moment, I just ignore small values. But, this has given me the idea of a better 'conform to terrain' method of standing. if val.x is the largest of the small values, they are on a left downward slope (or vv), and thus their idle animation should be one with the left foot lower than the right. If the opposite is true, we would lower the right foot instead, etc.....And one more note; the sprinting bool is non-stock, and is just an extension of any of the multitude of player set agility, speed, etc. resources. In our case, the datablock maxspeed is set to a normal walk speed. Various factors will cause your player to exceed this, such as going downhill, or adding any form of speed multiplier. Even stock Torque will exceed your DB value in some cases.
About the author
Recent Blogs
• Dynamic GUI• Mob Look
• Faster Polysoup
• DreamGames and Titas
• TSE Interior Decals
#2
This minor thing is of course completely unnessecary, but I found myself getting confused a few times when trying something new in this function. After 'indulging', the original method becomes senseless, so I simplified the whole thing and made it readable no matter what state of mind I'm in on coding nights.
Another main reason for this is we really needed numerous different velocity based animations. Those MUST be done right in the animations themselves, or the code will simply not transisition properly. I find it far easier to do the animation speeds the best I can, and then manually set the speed via code.
11/02/2005 (2:56 pm)
Nod, you did a great job expanding my original resource, and thus now have the headache of helping everyone who can't understand it :)This minor thing is of course completely unnessecary, but I found myself getting confused a few times when trying something new in this function. After 'indulging', the original method becomes senseless, so I simplified the whole thing and made it readable no matter what state of mind I'm in on coding nights.
Another main reason for this is we really needed numerous different velocity based animations. Those MUST be done right in the animations themselves, or the code will simply not transisition properly. I find it far easier to do the animation speeds the best I can, and then manually set the speed via code.
#3
11/19/2005 (1:39 pm)
I just wrote a post about how I switched to using this system over the stock one, but GG ate it. :( Anyway, this is a very nice resource, and it looks to work alot better than the stock code and it's alot easier to follow. Nice work!
#4
06/21/2006 (8:01 am)
Excellent resource, I've switched to this system as well. My own solution for picking animations seemed to be breaking under 1.4 and this solved my problems.
#5
11/15/2006 (10:21 pm)
Josh, where is your expanded resource?
#6
01/26/2008 (8:35 am)
Good! Much clear than the original. 
Torque Owner Josh Moore