LightRecoil - setActionthread vs. playthread
by Martin Banks · in Torque 3D Professional · 09/09/2009 (3:09 pm) · 14 replies
I have created a character and a weapon. I have set up the weapon states so that there is a ready and fire. The fire state defines lightrecoil, and the character has a corresponding light_recoil animation. I copied this relationship setup from the full example supplied with beta5. However, unlike the example project characters (boombot etc.) when my character fires, the item anim plays as expected, but the character's light_recoil gets to the end and then is stuck on its final frame.
I can then walk around, and instead of returning to my character's idle animation, it poses right back to the final frame of the weapon fire animation.
I've read that if a nonlooping animation is played using playthread(), then it will stick to the final frame until stopThread() is called on that animation slot. However, I'm not sure if that is the method behind playing the light_recoil animation. Would this behavior also occur using setActionThread()?
What am I missing here?
Thanks in advance.
I can then walk around, and instead of returning to my character's idle animation, it poses right back to the final frame of the weapon fire animation.
I've read that if a nonlooping animation is played using playthread(), then it will stick to the final frame until stopThread() is called on that animation slot. However, I'm not sure if that is the method behind playing the light_recoil animation. Would this behavior also occur using setActionThread()?
What am I missing here?
Thanks in advance.
About the author
#2
I believe you are using it with wait/hold flag.
09/14/2009 (6:03 pm)
How do you use setActionThread() ?I believe you are using it with wait/hold flag.
#3
I simply call it in script with the name of the animation sequence and no other parameters.
Unless it defaults to wait/hold, then I can't see how that is being set.
09/14/2009 (6:08 pm)
@Picasso I simply call it in script with the name of the animation sequence and no other parameters.
setActionThread("animName");Unless it defaults to wait/hold, then I can't see how that is being set.
#5
My root animation works. The light_recoil is not looping, and is not exported as a blend. It simply sticks to the last frame, and prevents the 'run' animation from playing every. So the sequence is as follows:
idle, run, idle, Lrecoil, idle, try to run and now its sticks.
At this point I then noticed the velocity was stalled at zeroes, as noted above in Player::pickActionAnimation().
09/15/2009 (11:40 am)
@WCIT My root animation works. The light_recoil is not looping, and is not exported as a blend. It simply sticks to the last frame, and prevents the 'run' animation from playing every. So the sequence is as follows:
idle, run, idle, Lrecoil, idle, try to run and now its sticks.
At this point I then noticed the velocity was stalled at zeroes, as noted above in Player::pickActionAnimation().
#6
player.cpp
after the console method setactionthread(),add a new one:
in player.h correct setactionthread to be in public,so we now have an access to it :
replace with this one:
And do not forget to add setMaskBits(ActionMask) in the real setactionthread();
Test your animation with setActionThread2() method.
Now you have an access to all flags.
Actually animation problems are very hard to be solved from torquescript,because of the little functionality.
I believe you should move to c++ to trace out what exactly happens.
09/15/2009 (1:36 pm)
OK,try this one:player.cpp
after the console method setactionthread(),add a new one:
ConsoleMethod( Player, setActionThread2, bool, 3, 8, "action,forward,hold,wait,fsp,forceSet)")
{ //parameters : action,forward,hold,wait,fsp,forceSet
object->setActionThread(dAtoi(argv[2]),dAtob(argv[3]),dAtob(argv[4]),dAtob(argv[5]),dAtob(argv[6]),dAtob(argv[7]));
return true;
}in player.h correct setactionthread to be in public,so we now have an access to it :
virtual void setActionThread(U32 action,bool forward,bool hold = false,bool wait = false,bool fsp = false, bool forceSet = false);
replace with this one:
public: virtual void setActionThread(U32 action,bool forward,bool hold = false,bool wait = false,bool fsp = false, bool forceSet = false); protected:
And do not forget to add setMaskBits(ActionMask) in the real setactionthread();
Test your animation with setActionThread2() method.
Now you have an access to all flags.
Actually animation problems are very hard to be solved from torquescript,because of the little functionality.
I believe you should move to c++ to trace out what exactly happens.
#7
I am actually in the engine code tracking this down, the reference above to discovering the zero velocity (which I think is a lead to the problem here) that happens while the character is moving forward/back/side was discovered in player.cpp
Player::pickActionAnimation() sets the index into the action sequence list, then calls Player::setActionThread().
09/15/2009 (3:05 pm)
thanks, picasso I'm definitely gonna try this.I am actually in the engine code tracking this down, the reference above to discovering the zero velocity (which I think is a lead to the problem here) that happens while the character is moving forward/back/side was discovered in player.cpp
Player::pickActionAnimation() sets the index into the action sequence list, then calls Player::setActionThread().
#8
Only those with the colinear vector directions - run,back and side.
If eventually there is no velocity,root is set.
The rest is handled in various ways - setSequence(),then transitioning to another sequence and so....
Look for more information ActionAnimationList at the beginning of the file.
If you want to see there is no problem with the velocity,you can call setActionThread() with forceset+wait directly in c++.
Your problem appear to be setting the action thread all the time,setting it twice,holding it or high sequence priority.
09/15/2009 (3:16 pm)
pickActionAnimation() sets the sequences in relation to player's velocity.But not all of them.Only those with the colinear vector directions - run,back and side.
If eventually there is no velocity,root is set.
The rest is handled in various ways - setSequence(),then transitioning to another sequence and so....
Look for more information ActionAnimationList at the beginning of the file.
If you want to see there is no problem with the velocity,you can call setActionThread() with forceset+wait directly in c++.
Your problem appear to be setting the action thread all the time,setting it twice,holding it or high sequence priority.
#9
09/15/2009 (4:27 pm)
Ok, so I renamed my light_recoil sequence to "squeeze" and then called setActionThread() in script Player::onTrigger for trigger0 and now everything appears to be working with no unexpected blending or sticking.
#10
You don't need even to use setActionThread(),just rename your file to "light_recoil", "medium_recoil" or "heavy_recoil" and advanceTime() will advance your animation.
setActionThread() is intended to be used for an ActionAnimation thread,not mRecoilThread.
This mRecoilThread seems as a thread that controls a specific part of the player.So it depends how you provide it.
If you export "light_recoil" like a normal animation,it will advance over the whole player (like the ActionAnimation.thread).
So you have two threads working on the player,that's why it is messed up.
09/15/2009 (4:37 pm)
Right now i take a look at the code and see there is an additional thread (mRecoilThread) for the recoil animation.You don't need even to use setActionThread(),just rename your file to "light_recoil", "medium_recoil" or "heavy_recoil" and advanceTime() will advance your animation.
setActionThread() is intended to be used for an ActionAnimation thread,not mRecoilThread.
This mRecoilThread seems as a thread that controls a specific part of the player.So it depends how you provide it.
If you export "light_recoil" like a normal animation,it will advance over the whole player (like the ActionAnimation.thread).
So you have two threads working on the player,that's why it is messed up.
#11
http://www.garagegames.com/community/forums/viewthread/76357
Actually, I would call it a "bug" (same as in TGEA171 in mentioned thread).
09/15/2009 (4:50 pm)
I think this could help:http://www.garagegames.com/community/forums/viewthread/76357
Actually, I would call it a "bug" (same as in TGEA171 in mentioned thread).
#12
I think there is something going on with the way the hinted/default actions are initiated that was causing the problem. Seems that maybe the recoil thread is sticking and holding.
09/15/2009 (4:58 pm)
@Picasso - I had the sequence named to light_recoil initially and it was not playing consistently, and it was giving me the sticking/unexpected blendfreeze problems. The rest of the history happens at the beginning of the thread.I think there is something going on with the way the hinted/default actions are initiated that was causing the problem. Seems that maybe the recoil thread is sticking and holding.
#13
If I understand correctly, then you ran across these problems as a result of having several recoil animations defined, which I notice were defined as sequences in your TSShapeConstructor(myCharShape).
In my example I only had one recoil (light_recoil), but it was originally a collada import so my sequences were added in the myChar.cs file myCharShape::onLoad via addsequence().
09/15/2009 (5:45 pm)
@Fydoor I looked at the problems you describe in that post for recoil. http://www.garagegames.com/community/forums/viewthread/76357If I understand correctly, then you ran across these problems as a result of having several recoil animations defined, which I notice were defined as sequences in your TSShapeConstructor(myCharShape).
In my example I only had one recoil (light_recoil), but it was originally a collada import so my sequences were added in the myChar.cs file myCharShape::onLoad via addsequence().
#14
you get unexpected behaviour of the body because you did export your recoil animation as a full body animation.
This animation should control a specific part of the body.
When you call setactionthread(),you change the sequence control.
You move the control to the action animation thread and you can not play a second sequence while playing your recoil sequence.
And it is normal.
A thread can control a single sequence.
That's why there is a recoil thread - to play two sequences at the same time.
If your animation is not cyclic,it will hold the full body animation at end.It will overlap the animation bone control of the main action thread,because mRecoilThread is played after it (look at updateAnimation()) - this is exactly what you see.
If it is cyclic,it will run all the time.
You can not tell 2 sequences to control same bones on the player at the same time.
I believe now you understand the problem.
You can workaround this by:
- removing all keyframes for the rest body animation
- use fullbody animation (as now),but separate the sequences in different priorities.
09/16/2009 (2:33 pm)
Martin,you get unexpected behaviour of the body because you did export your recoil animation as a full body animation.
This animation should control a specific part of the body.
When you call setactionthread(),you change the sequence control.
You move the control to the action animation thread and you can not play a second sequence while playing your recoil sequence.
And it is normal.
A thread can control a single sequence.
That's why there is a recoil thread - to play two sequences at the same time.
If your animation is not cyclic,it will hold the full body animation at end.It will overlap the animation bone control of the main action thread,because mRecoilThread is played after it (look at updateAnimation()) - this is exactly what you see.
If it is cyclic,it will run all the time.
You can not tell 2 sequences to control same bones on the player at the same time.
I believe now you understand the problem.
You can workaround this by:
- removing all keyframes for the rest body animation
- use fullbody animation (as now),but separate the sequences in different priorities.
Torque 3D Owner Martin Banks
ArchieMD
Anyone else getting this issue?