Add Runtime Expression
Now we need to create an expression that will do the work for the travel from plane to plane. This is also where most of your work will be. We need goalWeights that change like we had before, but we need to have four of them working together. Let's start with the expression that we wrote in Example 3:
Particle: r Runtime before Dynamics C Runtime after Dynamics f* Creation Editor: | Expression Editor ^"j Expression: // Creation
BallShape.goalU = 0.5; BallShape.goalV = 0.5;
Figure 19.39 Goal expression in Expression Editor.
The above statements worked fine for two planes and the particle, but we need more now. Instead of relying on the absolute value of the sine and cosine functions, let's use a curve function that will give us more control. The function linstep (linear step) will work. The syntax for linstep follows:
linstep (value_from, value_to, percentage) So let's change the expression for the goalWeights to goalWeight[0] = linstep(0.0, 1.0, sin(time));
Figure 19.40 shows a plot of the sin, cos, and the linstep functions. When the sin and cos go negative, the linstep function waits until it starts getting positive numbers to go from 0.0 to 1.0 and then back from
- Figure 19.40 sin, cos, and linstep.
Goal Smoothnes 1 Goal Weighty] 0.137 Goal Weight(1 ] 0 991 Goal Weight^] 0 296 Goal Weightß] 0 Cache Data oft
Figure 19.41 Goal Weight attributes in Channel Box.
1.0 to 0.0. This will buy us some time and let another set of sin and cos functions that are offset from the first pair make their transition from 0.0 to 1.0 and back to 0.0.
Now we need to offset the other two. These functions are set into motion through the use of the time command in Maya. So we need to offset time's output and feed it into the other set of sin and cos. Don't type it in yet, but the following code segment shows how we'll do that.
goalWeight[2] = linstep(0.0, 1.0, sin((time) + 24));
goalWeight[3] = linstep(0.0, 1.0, cos((time) + 46));
The two numbers 24 and 46 are the time shift numbers that will enable sin and cos to offset their waves. We arrived at these numbers by experimenting with the expression and watching the output in the Channel Box (Figure 19.41).
We also need to add our freq attribute as before, but this time we will put it in the expression and change it there if necessary. Add it in the (time) area. Our runtime expression thus far follows:
- Runtime
- Add freq and set it to 4 float Sfreq = 4.0; // Main expression goalWeight[0] = linstep(0.0, 1.0, cos((time * Sfreq))); goalWeight[1] = linstep(0.0, 1.0, sin((time * Sfreq))); goalWeight[2] = linstep(0.0, 1.0, sin((time * Sfreq) + 24)); goalWeight[3] = linstep(0.0, 1.0, cos((time * Sfreq) + 46));
Let's put the expression into MEL syntax and enter it:
dynExpression -runtimeAfterDynamics -s (
"// Add Sfreq and set it to 4.\n\n" + "float Sfreq = 4.0;\n\n" + "// Main expression\n\n" +
"goalWeight[0] = linstep(0.0, 1.0, cos((time * $freq)));\n" + "goalWeight[1] = linstep(0.0, 1.0, sin((time * $freq)));\n" + "goalWeight[2] = linstep(0.0, 1.0, sin((time * $freq) + 24));\n" +
"goalWeight[3] = linstep(0.0, 1.0, cos((time * $freq) + 46));" ) BallShape;
Now let's write the MEL script. In a text editor of your choice, enter the following code:
- /
- MEL script: ballTravel //
- Notes: This is designed to work with the scene chapter19.ma //
- Usage: Select the four NURBS planes in the scene in the order that // you want and execute the script //
- Extra: The runtime expression variable $freq can be changed in the
- Expression Editor for travel speed changes global proc ballTravel( ) {
- Get the plane order from the selection string $planes[] = "ls -sl";
- Check to see if we have enough planes if (size($planes) != 4) {
error "We need more planes\n"; // This will stop the script. }
- Make a particle and place it at center of first selected plane float $Pstart = "xform -q -a -translation $planes[0]"; particle -n Ball -p $Pstart[0] $Pstart[1] $Pstart[2] -c 1;
- Set particle to sphere type setAttr BallShape.particleRenderType 4;
- Add goals in order of selection goal -w 0 -utr 0 -g $planes[0] Ball;
// Add goalU and goalV to Ball addAttr -ln goalU -dt doubleArray BallShape;
addAttr -ln goalUO -dt doubleArray BallShape;
addAttr -ln goalV -dt doubleArray BallShape;
addAttr -ln goalVO -dt doubleArray BallShape;
- Expression section
- Add creation and runtime expressions dynExpression -s (
"// Creation \n\n" + "goalU = 0.5;\n" + "goalV = 0.5;\n\n"
) -creation BallShape;
dynExpression -runtimeAfterDynamics -s (
"goalWeight[0] = linstep(0.0, 1.0, cos((time * $freq)));\n" +
"goalWeight[1] = linstep(0.0, 1.0, sin((time * $freq)));\n" +
"goalWeight[2] = linstep(0.0, 1.0, sin((time * $freq) + 24));\n" +
"goalWeight[3] = linstep(0.0, 1.0, cos((time * $freq) + 46));"
- BallShape;
- End the script and source it. Load scene and // type ballTravel in Script Editor
- End of global proc
Source the script; then select the four planes, and run it by typing ballTravel in the Script Editor. Then, rewind and play back your scene (Figure 19.42).

- Figure 19.42 The ball bounces among all four planes.
Post a comment