Game Development Community

Playing an animation (playThread) more than once?

by Jacob Smith · in Torque Game Engine · 05/22/2004 (6:49 pm) · 16 replies

I have successfully created an object with collision information, a simple bone structure, a single animation within the modeler (using trueSpace 6.1) and exported it to a DTS file (using the Dark Industries DTS exporter).

NOTE: The animation is embedded within the DTS file.

I've created a simple non-static object that uses the exported DTS file that plays the animation when a collision occurs:

function BendY::onCollision( %this, %obj, %col )
{
    %obj.playThread(0, "BasicBend");
}

The animation plays successfully the first time I run into the object. The problem is that the animation never plays again (the next time I collide with the object).

I've verified that the onCollision call is being made over and over. I tried adding a "%obj.stopThread(0);" call before the playThread, but that didn't seem to help.

How can I play an animation again?
Is there a way to cancel the current animation?

Thanks

#1
05/23/2004 (12:03 am)
Hi Jacob

Try to use

%obj.setThreadDir(0,true);
or
%obj.setThreadDir(0,false);
#2
05/23/2004 (4:15 pm)
Quote:%obj.setThreadDir(0,true);
or
%obj.setThreadDir(0,false);

Well, this allowed me to change the direction of the animation, but it did not allow me to restart the animation.

I'd like to be able to stop and restart the animation from the beginning (in a discontinuous manner).

Thanks.
#3
05/31/2004 (12:09 am)
@Jacob: I'm having the same issue. stopThread() doesn't seem to do anything. (For example, if I set the animation to be cyclic and then let it play continously.)

It's like stopThread()/playThread() just ignore any changes. I'm stepping through the code right now to figure this out.

In my case, I want my character to do attack moves as blend animations on top of the usual setActionThread(). Just like your example, it works beautifully the first time -- but then playThread() doesn't seem to do anything after that one time.

I've been searching the GG site for the last hour for information but I have been having little luck. (Grrr, we need full-body text message search! I'd even pay a subscription rate to get this service, to make up for the extra server load.)

Anyway, I'll let you know if I find anything. Hopefully, someone more knowledgable about Shapebase/ShapeInstance will clue us in...

EDIT: Strange...The PlayThread code is going through the motions. It sets all the appropriate parameters, insofar as I can tell. But nothing seems to happen when it fires twice against a non-cylic animation. Maybe this is a client/server sync issue? I can't believe we are the first people to notice something is wrong with PlayThread/StopThread. What are we doing wrong? Reusing slot numbers?
#4
06/06/2004 (5:12 pm)
A little bump, plus some more information.

Well, I've been looking through PlayThread()/StopThread() and the TSThread classes.

First of all, when you PlayThread() on a non-cyclic thread, it will play until it reaches the end (1.0 on time scale) and then stop at that value. However, it will continue to leave the thread in a Thread::Play state. At first I tried changing this behavior, but it screws up some other things. (For example, what if you want the thread to remain at 1.0 time once it finishes? A better way to handle this would be add a flag for a sequence called 'hold last frame'. If HLF was set, it would behave as it does now, otherwise it would set the sequence position back to 0.0.)

Anyway, you can fix this by stopping the thread. But, as Jacob noticed, calling stopThread() and then playThread() just doesn't work.

I still haven't figured it out yet entirely, but it seems that the shapeBase object needs time to "catch up" for state changes between played/stopped threads, so calling a stop and then play so close to each other yields nothing. (I think it's because the state changes need to propagate through the sim, from server to client.)

Anyway, here's how I got around it. Simply call the stopThread a certain amount of time after you've invoked playThread. This allows the animation to clean itself up and gives the thread state machine time to syncronize. For example, in script you'd do this:

%obj.playThread(1,"punch0");
  %obj.schedule (500, "stopThread", 1) ;

Cyclic animations do not have this trouble because, well, there's no concept of a finished cyclic. You have to stop those manually anyway.

A better way to handle this would be to create a new method called "playThreadandStop()" which would act like a one-shot animation. If you wanted your animation to hold its last frame, use playThread(), but if you want to cause an animation to reset upon termination, then use the hypothetical playThreadandStop().

More info once I research this a bit more.
#5
10/11/2005 (3:35 pm)
I suggest reversing the calls instead of guessing how long the thread is, otherwise you risk a thread not actually getting stopped before the next time when you want to start the thread.

%obj.stopThread(1);
    %obj.schedule(0, "playThread", 1, "punch0");
#6
01/04/2007 (12:54 pm)
I found that scheduling the play to immediately follow the stop didn't work so well.... I followed Tony's advice but with the following lines:

%obj.stopThread(1);
    %obj.schedule(100, "playThread", 1, "punch0");

with some success. with a delay of 10 instead of 100 ms, it worked sometimes but not always.

i'm surprised at the design of Torque -- that it doesn't automatically stop/clear out a playThread when a non-cyclic animation has completed........ if anyone has a mod to fix this the right way instead of this timing-sensitive hack, please post! 100ms is not a big deal for the features we're adding now, but for gameplay every ms matters.
#7
01/04/2007 (12:57 pm)
I documented the functions where you need to look in another thread.
As usual, the search feature doesn't help me find my own posts so you're on your own looking for it.

Good luck!
#8
01/04/2007 (2:35 pm)
The problem is, when you play an animation in torque, it doest reay stop, it sits on the last frame of the animation, so if you call it again... its like "What? i am playing"

A small 3 frame animation that is something else called after the first (doesn't even need to animate anything) will fix this issue, as when you call the original animation again...it not still playing.
#9
01/04/2007 (2:43 pm)
@Exopolis Prod.
Have you tried using a looping animation and use stop, pause and playthread ?
I use it but you have a special case here so maybe its not working like you want.
#10
01/06/2007 (9:47 am)
Ahh.....Allyn; you clever rascul[better 'hack' than stop/play]! This playThread scheme has provided me[non coder] with tremendous difficulties running the same sequence twice in a row. I had an object that would play a random animation out of an index of sequences. The stopThread/playThread was as close as I got to get it working as I'd intended, but every time the same sequence was chosen from the random number generator twice in a row, the second calling always failed[guess I could add some sort of check to change direction of Thread??]. My echoes proved it, the calling happens, engine 'bails' on the 'playing' sequence, always with the same sequence getting called in succession.

You're suggesting using a Thread 'cleaner' to reset it after every calling of the animation; brilliant. Thanks!
#11
01/07/2007 (6:05 am)
Playthread(2,? i dont know if im sure but i think the number is amount of times
#12
02/06/2007 (9:21 am)
How do i get the playthread to be called by a trigger? Also how do i get a trigger to call the trigger that is calling the playthread. that may sound confusing but im stuck on it.
#13
02/06/2007 (9:28 am)
How do i get the playthread to be called by a trigger? Also how do i get a trigger to call the trigger that is calling the playthread. that may sound confusing but im stuck on it.
#14
02/06/2007 (10:56 am)
Do it in: onEnterTrigger, onLeaveTrigger, or onTickTrigger


function YourTrigger::onEnterTrigger(%this,%trigger,%obj)
{
%obj.stopThread(1);
%obj.schedule(100, "playThread", 1, "punch0");
}

sample trigger I made: www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=11601
#15
02/06/2007 (11:29 am)
Thanks rex.
#16
01/15/2008 (8:54 am)
Hi all, i am also having the same problem. I have create TSShapeConstructor with 23 desq in it. Now the player play the animation for every odd call. Otherwise it play the sequence0 animation. Console doesn't give me any error and while calling playthread i am passing the valid sequence. I also debugged the engine there also not found any thing. Is any one have any idea about this. Is there particular order to be followed while creating the TSShapeConstructor ?