Motionbuilder: Way to play one take after the next? ( Python )

Hey,
I’ve been trying to find a way to trigger a command after the timeline has finished playing. My goal being to build a tool which allows me to play multiple takes one after the other.

Has anyhow done anything similar or could point me in the right direction?

Thanks for your help.

I’m sure you can trigger it off with a script, but I’m not sure how to get the signal from the play button itself.

from pyfbsdk import *
import time
player_control = FBPlayerControl()
for each_take in FBSystem().Scene.Takes:
    # Set current take
    FBSystem().CurrentTake = each_take
    FBSystem().Scene.Evaluate()
    player_control.GotoStart()
    player_control.Play()
    time.sleep(0.1)
    FBSystem().Scene.Evaluate()
    while player_control.IsPlaying:
        FBSystem().Scene.Evaluate()
    else:
        continue

The only annoying thing is, if I triggered the player_control.Play(), then queried the player_control.IsPlaying, it was also return False unless I added the time.sleep() in there… But then this made the UI appear to freeze throughout the takes so you can’t actually see the player playing :confused:

Thanks Ryan, yeah I was getting similar issues to you. I have been playing with the system.OnUIIdle.Add and I thin that might be the key, but I haven’t got it to work yet.

Hi,
try this script:

from pyfbsdk import FBSystem,FBPlayerControl,FBApplication

lSystem = FBSystem()
player = FBPlayerControl() 
player.LoopActive=False
TakeNo = 0

def playNextTake(control, event):
    global player, lSystem, TakeNo
    if str(event.Type)=="kFBPlayerControlStop" and lSystem.LocalTime.GetFrame()!=0: 
        if TakeNo == len(lSystem.Scene.Takes)-1:
            lSystem.Scene.Evaluate()
            player.OnChange.RemoveAll()

        lSystem.Scene.Evaluate()
        TakeNo = TakeNo + 1       
        if TakeNo <= len(lSystem.Scene.Takes)-1:
            lSystem.CurrentTake = lSystem.Scene.Takes[TakeNo]
            player.GotoStart()
            player.Play()
                              
player.OnChange.Add(playNextTake)
lSystem.CurrentTake = lSystem.Scene.Takes[0]
player.GotoStart()
player.Play()

That’s great thanks. I found it worked all the time on a scene where i make new takes, but not 100% in a scene with animations in already…
I was looking at fixing this, but then I discovered OnChange does not exist in 2015, which I’m using at work :frowning: … So will have to think more about it, but thanks!

I changed it to OnUIIdle event, which exists in 2015 (I use 2017).
This Event is disabled when playback stops on last take.

from pyfbsdk import FBSystem,FBPlayerControl,FBApplication

lSystem = FBSystem()
player = FBPlayerControl() 
player.LoopActive=False
TakeNo = 0
      
def playNextTakeOnUIIdle(control, event):
    global player, lSystem, TakeNo
    if player.IsPlaying == False and lSystem.LocalTime == FBPlayerControl().ZoomWindowStop:
        if TakeNo == len(lSystem.Scene.Takes)-1:
            lSystem.Scene.Evaluate()
            lSystem.OnUIIdle.RemoveAll()

        lSystem.Scene.Evaluate()
        TakeNo = TakeNo + 1       
        if TakeNo <= len(lSystem.Scene.Takes)-1:
            lSystem.CurrentTake = lSystem.Scene.Takes[TakeNo]
            player.GotoStart()
            player.Play()
        
lSystem.CurrentTake = lSystem.Scene.Takes[0]
player.GotoStart()
player.Play()
lSystem.OnUIIdle.Add(playNextTakeOnUIIdle)

Great! that works thanks :slight_smile:

1 Like