More than one call playAction() in BGE

In my model, if I try to call playAction() more than once, only one playAction() got called. My code is as follows

import bge
obj=bge.logic.getCurrentController()
own=obj.owner
own.playAction('CubeAction',0,5,play_mode=bge.logic.KX_ACTION_MODE_PLAY)
own.playAction('CubeAction',30,60,play_mode=bge.logic.KX_ACTION_MODE_PLAY)

My idea is, based on the user input, different animations are played which is differentiated by the change in the timeline.

For example

For I am here

0,10 in timeline is played for “For”, 12,20 is played from “I” and so on.

Sample Blender file

1 Like

So you call the character to go left and at the same time you call it to go right.

What would you do, if you where the called one?

It seems you need to care about the timing.

e.g.
frame 0: play “For”
frame 30: play …

Sorry for the dump question. Just started with BGE. How could I set the frame? I thought it playAction() will run one after another in that code.

Sorry for the dump question

I thought playAction() will run one after another. Like first

own.playAction(‘CubeAction’,0,50,play_mode=bge.logic.KX_ACTION_MODE_PLAY)

will run and then

own.playAction(‘CubeAction.003’,30,60,play_mode=bge.logic.KX_ACTION_MODE_PLAY)

I didnt understand the last part of your question; “care about timing”. How to set the timing.

You need to detect the end of the previous action before you start the next one.

Example:
How to: create Action sequences with logic bricks - the power of the ActuatorSensor

Read the article. But couldn’t figure out how to do that from a Python script. Based on my example how to go about that?

If you use the Python API you have to stay with it. I suggest to check theAPI documentation

Basically you get 3 operations:

A) start the first animation
B) constantly check if the animation started with A) finished
C) start the next animation

Went through the API. Couldn’t find a way to check whether the first animation finished or not? How to do that using Python API?

When I gave like this for attached blender file

import bge
obj=bge.logic.getCurrentController()
own=obj.owner
my_property=own['time']
test=0
def main():
    test=0  
    print("Hello")
    print(test)
    if test==0:
        own.playAction('CubeAction',0,10,priority=0,play_mode=bge.logic.KX_ACTION_MODE_PLAY)
        #print(own.getActionFrame())
        test=test+1
        print("Inside First")
        print(own.isPlayingAction())
        #own.stopAction(0)
        print(own.isPlayingAction())
        #if not own.isPlayingAction():
    if test!=0:
        #print(own.getActionFrame())
        print(my_property)
        #own.setActionFrame(30,0)
        print("Inside Second")
        if not own.isPlayingAction():
          own.playAction('CubeAction',30,50,play_mode=bge.logic.KX_ACTION_MODE_PLAY)
main()

But when I gave a stopAction() before the if not own.isPlayingAction():, only the second action works.

Hi

By looking for a code example on the bge function setActionFrame I reached this thread.

Not finding an example, I tried to fix abd modify the code given as an example.

The answer is much too late, but it can be useful for new programmers.

I commented the source code as a basis for future readers who have the same problem.

Test.py (5.9 KB)

#JL 20230307 code correction and test  On UPBGE 0.3+alpha   blender 3.5.0 alpha
#from   https://blenderartists.org/t/more-than-one-call-playaction-in-bge/626211/9
#   need a squence animation on Cube with at least 0 ... 100 frames to run

#   Toggle System console to show the debug message
#
#    you can turn print lines into comments.
#

# by thinking state machine  :   https://en.wikipedia.org/wiki/Finite-state_machine
#
#               start :
#              is step 1 started ?  NO is equivalent to : own[test]==0
#                    tested on line 63
#                 if False   put 1 in own["test"] to start step 1  ( changing state  of the state machine)
#
#              is step 1 ended ? 
#                    tested on line 81      not ended if test = 1 ; ended if test == 2
#
#              if ended  step 1  then start step 2 by test = 2  ( changing state  of the state machine)
#              
#                     line 77 show transition step1 -> step2 by moving uo the Cone
#                     line 92-98    debug console message
                        
#              new machine state start on line 91.    sequence 2 animation start on line 100                
#              is step 2 complete ? (so as not to repeat the second step)
#              nod=t the end while test =3      end il test = 4
#                      line 103              wait the end of the sequnce 2 animation   and the end of this state of the state machine

#                     if test = 4 it causes the end of the game 
#              in a real game you have to decide what to do next if own["test"] = 4
#
#                      détection of the new sttate start on line 113     if test == 4 :  
#
#                      this last state end the Game.
#
#                       message on line   122-124

#                       real exit on line 129     code     bge.logic.endGame () 
#
#     Cone position show frame 50 position  at the frame 50 of the Cube

#program start
import bge

#cgetting controller and object owner
obj=bge.logic.getCurrentController()
own=obj.owner
my_property=own['time']
print ( " my_property=own['time'] = ", my_property )
#test=0  #bad idea / is repeated on each loop

#the main definition
def main():
    #test=0  #bad idea / is repeated on each loop
    print ("\n"*2)
    print("Hello")
    print ( " my_property=own['time'] = ", my_property )
    test = own ["test"]
    print(test)
    
    #firt test test  = 0 on the first loop.
    if test==0:
        own ["test"] = 1    #the next loop is no more the first time
        #starts the first sequence of the animation          newe state  of the state machine :   start of playing first sequence
        own.playAction('CubeAction',0,50,priority=0,play_mode=bge.logic.KX_ACTION_MODE_PLAY)
        
        #print(own.getActionFrame())
        #test=test+1 #bad idea / no test
        print("Inside First own ['test']  = ", own ['test'])   #debug message
        a = own.isPlayingAction()
        print("own.isPlayingAction() = ", a )
        #if not a :  test +=1
#        if not a :  own ["test"] = 1
        #own.stopAction(0)
        #print(own.isPlayingAction())
        #if not own.isPlayingAction():
    #if test!=0:  #bas idea / repeat second call

    #waiting for the end of the first frame sequence 0 50      state machine wait for the end condition of the actual state
    if test==1: #wait the end of frst step
        a = own.isPlayingAction()
        print(" wait end of step 2   own.isPlayingAction() = ", a )    #debug message
        if not a : 
            print ("Not a == True")
            test = 2   #saves the end of the first sequence    the end condition of the actual state  is ON  (state machine)
            #move the Cone to show the transition
            bge.logic.getCurrentScene().objects["Cone"].worldPosition[2]*=-1   #move the Cone to show the end of the first sequence on 3D View
            
     #test condotion for starting step 2
    if test==2:  #start step 2                        test new state start condition  (state machine) 
        own ["test"] = 3 #preserve from step 2 repetition 
        #print(own.getActionFrame())
        print(my_property)
        #own.setActionFrame(30,0)
        print("Inside Second  own ['test']  = ", own ['test'])         #debug message
#        if not own.isPlayingAction():

         #run the second sequence form from frame 50 to frame 100
        own.playAction('CubeAction',50,100,play_mode=bge.logic.KX_ACTION_MODE_PLAY) # start the next sequence and a new state of the state machine
        
        #ETransition message
        print ("\n"*20)
        print ("/\\"*30)
        print ("/\\"*30)
        print ("<<<<<<<<<<<<<<<<    Transition    >>>>>>>>>>>>>>>>")     #debug message
        print ("\\/"*30)
        print ("\\/"*30)
        print ("\n"*20 )
        
    #waitinf the end of second sequence
    if test==3: #wait the end of step 2      waiting for end  condition of the state  (state machine) 
        a = own.isPlayingAction()
        print("Waiting end of step 2   own.isPlayingAction() = ", a )
        if not a : 
            print ("Not a == True")                                         #debug message
            own ['test'] = 4   #signal for reseting  own ['test']
            test = 4     #save current state end signal                        for the state machine evolutiuon
            #putting own ['test'] = 0 will restart the whole sequence
            
    # The End
    if test == 4 :                                      # to reach the new state of the state machine   (the last one)
        #End message
        print ("\n"*10)
        print ("<<<<<<<<<<<<<<<<    Game Over    >>>>>>>>>>>>>>>>")                  #debug message
        print ("\n"*10)
        
        #End of the game
        bge.logic.endGame () 
        
        
#the main call        
main()

UPBGE_anim_frame_0.blend (925.6 KB)