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


#1

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.


#2

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:


#3

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.


#4

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()

#5

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!


#6

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)

#7

Great! that works thanks :slight_smile: