Open topic with navigation
Tutorial: Creating a task
With viztask, you can pause the execution of a code while waiting for
some event to occur. Task scheduling can be an extremely handy way to
handle the flow of activity in a world.
Start the script
If you have trouble getting the code
in this tutorial to work, you can find the complete example script createTask.py in the \tutorials\flowControl
directory.
In this example, we'll set up an interaction between two avatars, pausing
for timers, keystrokes, and actions and animations. First, add some avatars,
a room, and some text to your script:
import viz
import vizact
viz.setMultiSample(4)
viz.fov(60)
viz.go()
#Add a room.
dojo = viz.addChild('dojo.osgb')
#move the viewpoint
viz.MainView.move([0,0,-5])
#Add some avatars and place them in the room.
male = viz.addAvatar('vcc_male.cfg')
female = viz.addAvatar('vcc_female.cfg')
female.setPosition([-2,0,0])
female.setEuler([90,0,0])
male.setPosition([2,0,0])
male.setEuler([-90,0,0])
#Animate them.
male.state(1)
female.state(1)
#Add some text.
question_text = viz.addText('Hit spacebar to start',
viz.SCREEN)
question_text.setScale([.4,.4,.4])
question_text.setPosition([.35,.75,0])
question_text.setBackdrop(viz.BACKDROP_OUTLINE)
Next, we'll import viztask and use it
to schedule a function. By scheduling this function with <viztask>.schedule, we enable the ability
to yield for a events or conditions. When you look at our function you
can see a couple yield statements that let
us yield first for a keystroke and then for one second to pass. The female
avatar will wait to start dancing until you hit the spacebar and then
the male will wait one second before walking over to her. Run
this script now and see how it goes.
#Import the viztask module.
import viztask
#Create a task.
def myTask():
#Wait for a keypress.
yield viztask.waitKeyDown( ' ' )
#Animate the female.
female.state( 5 )
#Wait for a second.
yield viztask.waitTime( 1 )
#Make the male walk.
male.addAction(
vizact.walkTo( [-1,0,0] ) )
#Schedule the task.
viztask.schedule( myTask() )
Now we'll add a bit of code to get the male dancing once he reaches
the female. The challenge here is that we don't want the male to start
dancing until he's finished walking. To accomplish this, we'll use a yield statement to add the walking action to the
male. The scheduler will wait until that action is finished before proceeding.
Replace
the entire snippet of code that you just added and replace it with the
code below. Try running the script again.
#Import the viztask module.
import viztask
#Create a task.
def myTask():
#Wait for a keypress.
yield viztask.waitKeyDown( ' ' )
#Animate the female.
female.state( 5 )
#Wait for a second.
yield viztask.waitTime( 1 )
#Make the male walk and wait for
him to finish the action.
yield viztask.addAction( male, vizact.walkTo( [-1,0,0] ) )
#Make the male dance.
male.state( 5 )
#Schedule the task.
viztask.schedule( myTask() )
We'll replace that chunk of code one more time
and do several things with that modification. For one, we'll add a sub
task within our task. The scheduler will call that task and wait for it
to finish before proceeding. In this case we'll wait for the user to hit
the 'n' key. We'll also change the script
so that each task has a while True statement
within it. This statement tells the scheduler to continue looping through
that code until the function returns a value or is killed (with <viztask:Task>.kill ). That'll let us
run through this series of events indefinitely and, in the case of the
subtask, wait for the right feedback to continue. The other useful thing
we've done with this modification is to use the data from an event within
our function-- The
viztask.waitKeyDown command returns a data object (viz.Data)
with information about which key was pressed. Try
replacing the chunk of code we've been tweaking with the code below, then
run it and see how it goes.
#Import the viztask module.
import viztask
#Create a task.
def myTask():
#As long as the task is running
. . .
while True:
question_text.message( 'Hit the spacebar to begin.' )
#Wait for
a keypress.
yield
viztask.waitKeyDown( ' ' )
#Animate
the female.
female.state( 5 )
#Wait for
a second.
yield
viztask.waitTime( 1 )
#Make the
male walk and wait for him to finish the action.
yield
viztask.addAction( male, vizact.walkTo( [-1,0,0] ) )
#Make the
male dance.
male.state( 5 )
#Wait for
a sub task to finish.
yield
mySubTask()
#Give the
male a new animation.
male.state(9)
#Give the
female a new animation and wait for it to finish.
yield
viztask.addAction( female, vizact.animation(6) )
#Make the
male run.
male.addAction( vizact.walkTo( [2,0,-1],2.5,90,11 ) )
#Schedule the task.
viztask.schedule( myTask() )
def mySubTask():
#Until this function returns a value
or is killed. . .
while True:
#Set the
text's message.
question_text.message( 'Do they keep dancing? (y/n)' )
#Wait for
either 'y' or 'n' key to be pressed
d = yield viztask.waitKeyDown( ['y','n'] )
#If the
keystroke is an 'n'. . .
if
d.key == 'n':
question_text.message('')
#End the task.
return