GENERATE/PREV.gifGENERATE/NEXT.gif

Script Controllers

The following scriptable controllers are available in MAX, mirroring the expression controllers:

Float Script      float controller

Position Script      position Point3 controller

Point3 Script      Point3 controller

Rotation Script      rotation Quat controller

Scale Script      scale Point3 controller

They function in similar way to expression controllers, providing a properties dialog in which a script can be entered that is used to compute the controller value. The primary advantages of script controllers are:

  1. They can use all the features of the MAXScript language including loops, scripted functions, pathnames, etc.
  2. Almost any property of any object in the scene can be used to help compute controller values, including things like mesh vertices, values of properties at arbitrary frame times, and other non-animatable properties that are not accessible in Expression controllers.
  3. They can use MAXScript global variables to communicate and coordinate with other controllers and scripts in MAX.

properties

.script

lets you programmatically get and set the text for scripts. For example,

$foo.position.controller.script = "$baz.pos - [20,20,35]"

When you assign a Script controller to some parameter, a properties dialog becomes available through the right-mouse-button menu or the Properties button on the Track View toolbar. This dialog contains two text boxes and several buttons:

Script text box: You type the script to compute the controller value here. See the section below on writing controller scripts for details.

Result text box: This box shows the results of an evaluation or any error messages caused by errors in your script.

Evaluate button: Cause an evaluation of the controller script to be made and prints the result in the Result box. The evalutation is computed for the current position of the MAX time slider.

Load/Save buttons: Load and save scripts to text files.

Close button: Compiles and checks the controller script and if all is OK, close the properties dialog. Any problems result in a dialog box asking whether you really want to close the box with an incorrect script. If you do, the controller yields a null value (0, [0,0,0], etc.) when evaluated by MAX.

Writing Controller Scripts

MAX interprets the text you type into the Script text box as the body of a MAXScript block expression, so you can type as many expressions as you want on as many lines as you want and they are evaluated in turn and the value of the last expression is taken as the conroller value. This value must yield the right type for the controller, Float for float, Point3 for position, Quat for rotation, etc.

Because the text is effectively 'inside' a block expression, you can declare local variables which are visible only within the script and are temporary for one evaluation. You can also declare or access global variables that are shared with all other scripts in MAXScript and hold their values from one evaluation to the next.

A controller is always evaluated by MAX with respect to a specific animation time. This might be the current time slider or incrementing frame time if an animation is playing or a render is under way.

In the case of Script controllers, the time being evaluated is used to establish an automatic 'at time' context around the controller script, so any properties you access (outside of other explicit 'at time' expressions) yield the correct values for the current controller evaluation time. This means you don't have to do anything special in your scripts to work at the correct time. You can access the eval time if you need with the standard MAXScript variable, currentTime. You can also reference scene property values at other times by using explicit 'at time' expressions in your scripts, as in normal MAXScript programming.

Remember that MAXScript lets you write multi-line string literals, if you need.

Examples:

A position script keeping the object at the center of all other objects in the scene as they move about:

local pos = [0,0,0]

for o in objects where o != $foo do

pos += o.pos

pos / (objects.count - 1)

The above script computes the average position of all objects except the current one (written as $foo here) by setting up a local variable that iterates through all objects except $foo, accumulates a total position vector, and computes the average in the last line, which is the final result of the script.

A position script keeping the object attached to the highest vertex in a given object:

local high_index = 1, high_z = (getVert $foo 1).z

for i in 1 to $foo.numVerts do

if (getVert $foo i).z > high_z then

(

high_index = i

high_z = (getVert $foo i).z

)

getVert $foo high_index

The above script runs over the vertices in $foo remembering the index of the vertex with the largest z and returns that vertex's coordinates as the new position.

Limitations

Script controllers are not automatically updated when you interactively modify objects that they depend on.

If you move the time slider or if you animate the changes and then play the animation, the changes are reflected automatically. Because the scripts can refer to other objects in very indirect ways or conditional ways, it is not possible for MAXScript to automatically determine the objects a script depends on.