BONUS CHAPTER 21

Automating with MAXScript

IN THIS CHAPTER

Getting acquainted with MAXScript

Learning the MAXScript tools, such as the MAXScript Editor and Listener windows

Recording scripts with the Macro Recorder

Setting MAXScript preferences

Discovering the various script types

Writing your own scripts

Understanding the Visual MaxScript Editor interface

Building a custom rollout with the Visual MAXScript Editor

The Max designers went to great lengths to make sure that you are limited only by your imagination in terms of what you can do in Max. They've packed in so many different features and so many different ways to use those features that you could use Max for years and still learn new ways of doing things.

Despite Max's wide range of capabilities, there may come a time when you wish for a new Max feature. With MAXScript, you can actually extend Max to meet your needs, customize it to work the way you want, and even have it do some of the more monotonous tasks for you.

What Is MAXScript?

In this chapter, you'll look at MAXScript—what it's for and why in the world you would ever want to use it. But before getting into the nitty-gritty details, I'll start with a brief overview.

Simply put, MAXScript is a tool that you can use to expand the functionality of Max. You can use it to add new features or to customize how Max behaves, so that it's tailored to your needs and style. You can also use MAXScript as a sort of VCR; it can record your actions so you can play them back later, eliminating repetitive tasks.

You can use MAXScript to “talk” to Max about a scene and tell it what you want to happen, either by having Max watch what you do or by typing in a list of instructions that you want Max to execute.

The beauty of MAXScript lies in its flexibility and simplicity: It is easy to use and was designed from the ground up to be an integral part of Max. But don't let its simplicity fool you; MAXScript as a language is rich enough to let you control just about anything.

In fact, you have already used MAXScript without even knowing it. Some of the buttons and rollouts use bits of MAXScript to carry out your commands. And after you've created a new feature with MAXScript, you can integrate it into Max transparently and use it just as easily as any other Max feature.

MAXScript is a fully functional and very powerful computer language, but you don't have to be a computer programmer or even have any previous programming experience to benefit from MAXScript. In the next few sections, you'll look at some simple ways to use MAXScript. For now, just think of a script in Max as you would a script in a movie or play—it tells what's going to happen, who's going to do what, and when it's going to happen. With your scene acting as the stage, a script directs Max to put on a performance for you.

One final note before you dive in: MAXScript is so powerful that an entire book could be written about it and every last feature it supports, but that is not the purpose here. This chapter is organized to give you an introduction to the world of MAXScript and to teach you the basic skills you need to get some mileage out of it. What is given here is a foundation that you can build upon according to your own interests and needs.

MAXScript Tools

MAXScript is pervasive and can be found in many different places. This section looks at the MAXScript tools and how different scripts are created and used.

Let's look at some of the tools used in working with MAXScript. Max has several tools that make creating and using scripts as simple as possible.

The MAXScript menu

The MAXScript menu includes commands that you can use to create a new script, open and run scripts, open the MAXScript Listener window (keyboard shortcut, F11) orthe MAXScript Editor window, enable the Macro Recorder, open the Visual MAXScript Editor, or access the Debugger dialog box.

The New Script command o pens a MAXScript Editor window, a text editor in which you write your MAXScript. See the “MAXScript Editor windows” section later in this chapter for more on this editor window. The Open Script command opens a file dialog box that you can use to locate a MAXScript file. When opened, the script file is opened in a MAXScript Editor window, as shown in Figure 1. MAXScript files have an .ms or .mrc extension. The Run Script command also opens a file dialog box where you can select a script to be executed.

Note

When you use Run Script, some scripts do something right away, whereas others install themselves as new tools.

The MAXScript Listener command opens the MAXScript Listener window. You also can open this window by pressing the F11 keyboard shortcut. The Macro Recorder command starts recording a MAXScript macro. The MAXScript Listener and recording macros are covered later in this chapter.

FIGURE 1 MAXScript is written using standard syntax in a simple text editor window.

image

The MAXScript Utility rollout

You access the MAXScript Utility rollout, shown in Figure 2, by opening the Utilities panel in the Command Panel and clicking the MAXScript button. This opens a rollout where you can do many of the same commands as the MAXScript menu.

FIGURE 2 The MAXScript rollout on the Utilities panel is a great place to start working with MAXScript.

image

The MAXScript rollout also includes a Utilities drop-down list, which holds any installed scripted utilities. Each scripted utility acts as a new feature for you to use. The parameters for these utilities are displayed in a new rollout that appears below the MAXScript rollout.

Tutorial: Using the SphereArray script

Here's a chance for you to play around a little and get some experience with MAXScript in the process. In the Bonus Chapter 21 directory of the CD is a simple script called SphereArray.ms. It's similar to the Array command found in the Tools menu, except that SphereArray creates copies of an object and randomly positions them in a spherical pattern.

To load and use the SphereArray script, follow these steps:

  1. Select Create image Standard Primitives image Box, and drag in the Top viewport to create a Box object that has a Length of 10 and Width and Height values of 1.0.
  2. Select the box object, open the Utilities panel in the Command Panel (the icon is a hammer), and click the MAXScript button.

    The MAXScript rollout appears.

  3. Click the Run Script button in the MAXScript rollout to open the Choose Editor file dialog box, locate the SphereArray.ms file from the Bonus Chapter 21 directory on the CD, and click Open.

    The SphereArray utility installs and appears in the Utilities drop-down list. (Because SphereArray is a scripted utility, running it only installs it.)

  4. Choose SphereArray from the Utilities drop-down list. Make sure that the box object is selected.
  5. In the Sphere Array rollout, enter 50 in the Object Count field and 2.0 for the Radius field. Now click the Go! button to run the script.

    The script adds 50 copies of your box to the scene and randomly positions them 2 units away from the box's position.

Figure 3 shows the results of the SphereArray MAXScript utility. Notice that the SphereArray script looks much like any other function or tool in Max.

The MAXScript Listener window

Figure 4 shows the MAXScript Listener window (keyboard shortcut F11), which lets you work interactively with the part of Max that interprets MAXScript commands. The top pane of the Listener window (the pink area) lets you enter MAXScript commands; the results are reported in the bottom pane (the white area) of the Listener window. You can also type MAXScript commands in the bottom pane, but typing them in the top pane keeps the commands separated from the results. If you drag the spacer between the two panes, you can resize both panes as needed.

Note

When you first open the MAXScript Listener, the top pane is not visible, but if you drag on the divider, you can make both panes visible.

FIGURE 3 The results of the SphereArray MAXScript utility

image

FIGURE 4 The MAXScript Listener window interprets your commands.

image

When you type commands into either pane and press Enter, the MAXScript interpreter evaluates the command and responds with the results. For example, if you type a simple mathematical expression such as 2+2 and press Enter, then the result of 4 is displayed in blue on the next line. Most results appear in blue, but the results display in red for any errors that occur. For example, if you enter the command hello there, then a Type error result appears in red because the MAXScript interpreter doesn't understand the command.

Caution

The MAXScript interpreter is very fickle. A misspelling generates an error, but MAXScript is case-insensitive, which means that uppercase and lowercase letters are the same as far as Max is concerned. Thus, you can type sphere, Sphere, or SPHERE, and Max sees no difference.

The Listener window has these menus:

  • File: You can use this menu to close the window (Ctrl+W), save your work (Ctrl+S), run scripts (Ctrl+R), open a script for editing (Ctrl+O), or create a new script from scratch (Ctrl+N).
  • Edit: This menu is where you access all the common editing functions you need, such as cutting, pasting, and undoing.
  • Search: You use this menu for searching through the window to find specific text (Ctrl+F), find the next instance (Ctrl+G), or replace text (Ctrl+H).
  • MacroRecorder: This menu lets you set various options for the MAXScript Macro Recorder.
  • Debugger: This menu provides a way to open the Debugger dialog box.
  • Help: This menu provides access to the MAXScript Reference (F1).

Tutorial: Talking to the MAXScript interpreter

This tutorial gives you a little experience in working with the MAXScript Listener window and a chance to try some basic MAXScript commands.

To start using MAXScript, follow these steps:

  1. Choose File image Reset to reset Max.
  2. Choose MAXScript image MAXScript Listener (or press F11) to open the MAXScript Listener window.
  3. Click anywhere in the bottom pane of the Listener window, type the following, and press Enter:
    sphere()

    A sphere object with default parameters is created.

  4. Next enter the following in the lower pane, and press the Enter key:
    torus radius1:50 radius2:5

    Max creates a torus and adds it to your scene. As you specified in your MAXScript, the outer radius (radius1) is 50, and the radius of the torus itself (radius2) is 5. The output tells you that Max created a new torus at the origin of the coordinate system and gave that torus a name: Torus01.

  5. Now use MAXScript to move the torus. In the Listener window, type the following:
    $Torus01.position.x = 20

    After you press Enter, you see the torus move along the positive X-axis. Each object in Max has certain properties or attributes that describe it, and what you've done is access one of these properties programmatically instead of by using the rollout or the mouse. In this case, you're telling Max, “Torus01 has a position property. Set the X-coordinate of that position to 20.”

    Note

    The $ symbol identifies a named object. You can use it to refer to any named object.

  6. To see a list of some of the properties specific to a torus, type the following:
    Showproperties $Torus01

    A list of the Torus01 properties appears in the window.

Figure 5 shows the MAXScript Listener window with all the associated commands and results.

FIGURE 5 Use the MAXScript Listener window to query Max about an object's properties.

image

An important thing to understand from this tutorial is that you can do almost anything with MAXScript. Any property of any object that you can access via a rollout is also available via MAXScript. You could go so far as to create entire scenes using just MAXScript, although the real power comes from using MAXScript to do things for you automatically.

Tip

Max remembers the value of the last MAXScript command that it executed, and you can access that value through a special variable: ? (question mark). For example, if you type 5 + 5 in the Listener window, Max displays the result, 10. You can then use that result in your next MAXScript command by using the question mark variable. For example, you could type $Torus01.radius2 = ?, and Max would internally substitute the question mark with the number 10.

At the left end of the status bar, you can access the MAXScript Mini Listener control by dragging the left edge of the status bar to the right. By right-clicking in this control, you can open a Listener window and view all the current commands recorded by the Listener. Figure 6 shows this control with another command along with the objects from the last example.

FIGURE 6 The resulting objects created via the MAXScript Listener window

image

MAXScript Editor windows

The MAXScript Editor window is different from the MAXScript Listener. It enables you to open and edit any type of text file, although its most common use is for editing MAXScript files. Although you can have only one Listener window open, you can open as many editor windows as you want. Each opened script appears in a separate tab at the top of the Editor window.

To open a new MAXScript Editor window, you can choose MAXScript image New Script, choose File image New from the MAXScript Listener window, or click the New Script button in the MAXScript rollout in the Utility panel. You can also use MAXScript Editor windows to edit existing scripts.

To create a new script, opening both an Editor window and the Listener window is usually best. Then you can try out things in the Listener window, and when the pieces of the MAXScript work, you can cut and paste them into the main Editor window. Then you can return to the Listener window, work on the next new thing, and continue creating, cutting, and pasting until the script is done.

Tip

You can also send text back to the Listener window for Max to evaluate. Just select some text with the cursor or mouse, and press Shift+Enter (or just Enter on the numeric keypad). Max copies the selected text to the Listener window and evaluates it for you.

The File menu includes several commands for working with script files, including New, Open, Save, Save As, and Revert. Another command exports the opened script to HTML, RTF, PDF, LaTeX, or XML. The Editor also integrates with a Source Control repository. Finally, the Editor's File menu includes the ability to print out the opened script.

The Edit menu includes commands for undoing, redoing, cutting, copying, and pasting script sections between different scripts and to and from the Listener window. The Match Brace and Select to Brace commands let you easily create and edit scripts; the Block Comment command allows you to quickly comment out certain areas of script; and the Make Selection Uppercase lets you quickly make variables identifiable.

The Search menu includes Find and Replace features. Another feature finds text in a directory of files. You also can set bookmarks that allow you to quickly move to a specific point in the code. The Views menu includes options for making the editor appear full screen. You also can expand and contract bracketed sections of the script and display editor elements, including a toolbar, status bar, line numbers, and indentation guide.

The Tools menu includes the Evaluate All command. This command is a fast way of having Max evaluate your entire script. The result is the same as if you had manually selected the entire text, copied it to the Listener window, and pressed Enter. An Evaluate Selection option also is available. The Tools menu also includes access to the Visual MAXScript window with the New Rollout and Edit Rollout menu commands. You also have access to the various options and properties files including the User and Global Options, the Abbreviations file, and the MAXScript Properties file, as shown in Figure 7.

The Macro Recorder

The MAXScript Macro Recorder is a tool that records your actions and creates a MAXScript that can be recalled to duplicate those actions. Using the Macro Recorder is not only a quick and easy way to write entire scripts, but it is also a great way to make a working version of a script that you can then refine. After the Macro Recorder has created a MAXScript from your recorded actions, you can edit the script using a MAXScript Editor window to make any changes you want.

You can turn the Macro Recorder on and off either by choosing MAXScript image Macro Recorder or by choosing Macro Recorder image Enable in the MAXScript Listener window. The check mark next to the Macro Recorder command on the MAXScript menu indicates that the Macro Recorder is turned on.

When the Macro Recorder is on, every action is converted to MAXScript and sent to the MAXScript Listener window's top pane. You can then take the MAXScript output and save it to a file or copy it to a MAXScript Editor window for additional editing. The Macro Recorder continues to monitor your actions until you turn it off, which is done in the same way as turning it on.

FIGURE 7 The MAXScript Editor can open several script files at once.

image

The MacroRecorder menu in the MAXScript Listener window includes several options for customizing the macro recorder, including

  • Enable: This option turns the Macro Recorder on or off.
  • Explicit scene object names: With this option, the Macro Recorder writes the MAXScript using the names of the objects you modify so that the script always modifies those exact same objects, regardless of what object you have selected when you run the script again. For example, if the Macro Recorder watches you move a pyramid named $Pyramid01 in your scene, then the resulting MAXScript will always and only operate on the scene object named $Pyramid01.
  • Selection-relative scene object names: With this option, the Macro Recorder writes MAXScript that operates on whatever object is currently selected. So if (when you recorded your script) you moved the pyramid named $Pyramid01, you could later select a different object and run your script, and the new object would move instead.

    Note

    To decide which of these options to use, ask yourself, “Do I want the script to always manipulate this particular object, or do I want the script to manipulate whatever I have selected?”

  • Absolute transform assignments: This tells the Macro Recorder that any transformations you make are not relative to an object's current position or orientation. For example, if you move a sphere from (0,0,0) to (10,0,0), the Macro Recorder writes MAXScript that says, “Move the object to (10,0,0).”
  • Relative transforms operations: Use this option to have the Macro Recorder apply transformations relative to an object's current state. For example, if you move a sphere from (0,0,0) to (10,0,0), the Macro Recorder says, “Move the object +10 units in the X-direction from its current location.”
  • Explicit subobject sets: If you choose this option and then record a script that manipulates a set of subobjects, running the script again always manipulates those same subobjects, even if you have other subobjects selected when you run the script again.
  • Selection-relative subobject sets: This tells the Macro Recorder that you want the script to operate on whatever subobjects are selected when you run the script.
  • Show command panel switchings: This option tells the Macro Recorder whether or not to write MAXScript for actions that take place on the Command Panel.
  • Show tool selections: If this option is selected, the Macro Recorder records MAXScript to change to different tools.
  • Show menu item selections: This option tells the Macro Recorder whether or not you want it to generate MAXScript for menu items you select while recording your script.

Tutorial: Recording a simple script

In this tutorial, you'll create a simple script that squashes whatever object you have selected and turns it purple.

To create a script using the Macro Recorder, follow these steps:

  1. Open the Purple pyramid.max file from the Bonus Chapter 21 directory on the CD.

    This file includes a simple pyramid object.

  2. With the pyramid object selected, choose MAXScript image MAXScript Listener (or press F11) to open the MAXScript Listener window.
  3. In the Listener window, open the MacroRecorder menu and make sure that all the options are set to the relative and not the absolute object settings, thereby telling the script to work on any selected object instead of always modifying the same object.
  4. Returning to the MacroRecorder menu, select Enable. The Macro Recorder is now on and ready to start writing MAXScript. Minimize the Macro Recorder window (or at least move it out of the way so you can see the other viewports).
  5. Dock the MAXScript Listener window to the Left viewport by right-clicking the viewport name and choosing Views image Extended image MAXScript Listener.

    Now you can keep things out of the way while you work.

  6. With the Pyramid01 object selected, choose Modifiers image Parametric Deformers image XForm to add an XForm modifier to the object.
  7. Select the non-uniform scale tool and restrict it to the Y-axis. Right-click anywhere in the Front viewport to make it active (if it's not already), and then drag the Y-axis gizmo downward to squash the pyramid.
  8. In the Modify panel, click the color swatch next to the object name field to open the Object Color dialog box. Pick one of the purple colors, and click OK.
  9. The script is done, so in the MAXScript Listener window, choose MacroRecorder image Enable to turn off the Macro Recorder.
  10. Now it's time to try out your first MAXScript effort. Add a sphere to your scene. Make sure that it's selected before moving to the next step.
  11. In the top pane of the MAXScript Listener window, select all the text (an easy way to do so is by pressing Ctrl+A), and then hold down the Shift key and press the Enter key to tell Max to execute the MAXScript.

In Figure 8, you can see the script and the sphere that has been squashed and has changed color.

FIGURE 8 Running the new squash-and-turn-purple script

image

The MAXScript Debugger

The MAXScript Debugger, shown in Figure 9, is a separate window that allows you to stop the execution of a script using breaks and look at the variable's values as the script is being run. This information provides valuable information that can help to identify bugs with your script.

FIGURE 9 The MAXScript Debugger lets you check the values of variables as the script runs.

image

The MAXScript Debugger dialog box is opened using the Debugger menu command in the various MAXScript tool windows or using the MAXScript image Debugger Dialog menu command on the main interface. The Command field at the top of the Debugger window lets you input commands directly to the debugger. The Output area displays the results. Several buttons at the bottom of the Debugger window let you control how the debugger works:

  • Break: Causes the current script to break out of its execution
  • Run: Starts the execution of the current script
  • Evaluate: Executes the command entered into the Command field
  • Watch: Opens the Watch Manager window where you can specify distinct variables to watch
  • Config: Opens the MAXScript Debugger Parameters dialog box where you can configure the debugger
  • Stop: Halts the execution of the current script
  • Clear: Clears all the text in the Output field

Watching variables

The Watch button opens the Watch Manager, shown in Figure 10. Clicking the Variable column lets you type in a new variable to watch. The Value column displays the value of the listed variables as the script is executed.

FIGURE 10 The Watch Manager lets you watch the value of specific variables.

image

Using debugger commands

Once the execution of a script has been halted by clicking on the Break button, you can enter specific commands in the Command field at the top of the debugger and click the Evaluate button to execute them. Table 1 lists the available debugger commands.

TABLE 1 MAXScript Debugger Commands

Command What It Does
threads Displays a list of all current threads.
setThread (thread no.) Makes the specified thread number the active thread.
stack Dumps the stack for the active thread.
setFrame (frame no.) Makes the specified frame number the active frame.
locals (variable) Dumps the value for the specified variable for the active thread and frame. If no variable is listed, then all variable values are dumped.
getVar (variable) Gets the value of the specified variable.
setVar (variable) Sets the value of the specified variable.
eval (expression) Evaluates the specified expression.
? Displays a list of debugger commands.

Configuring the debugger

The Config button opens the MAXScript Debugger Parameters dialog box, shown in Figure 11. This dialog box includes several options for deciding when to break out of the script execution. It also lets you define the time for each break.

FIGURE 11 The MAXScript Debugger Parameters let you set the break cycle time, among other settings.

image

Setting MAXScript Preferences

The Preference Settings dialog box, opened with the Customize image Preference Settings menu command, includes a panel of MAXScript settings, shown in Figure 12. Using these settings, you can set which scripts load automatically, the default settings for the Macro Recorder, and even what font is displayed in the Script Editor window. The Use Fast Node Name Lookup option causes all indexed MAXScript names to be saved in a cache buffer to speed the execution of the script.

FIGURE 12 The MAXScript panel in the Preference Settings dialog box includes options for controlling MAXScript.

image

Max includes two directories in its default installation that can be used to automatically load scripts when Max starts. These directories are scripts and scriptsstartup, but you can change them using the Configure Paths dialog box. The Load Startup Scripts option causes any scripts in these directories to be loaded automatically when Max starts.

Types of Scripts

All scripts are not created equal, and Max categorizes different scripts based on how they work. For more information, the MAXScript online help provides exhaustive information on their various options.

The main thing to consider when deciding what type of script to create is the user interface. Ask yourself what the most logical user interface would be for the type of tool you're creating, and this gives you a hint as to which type of script is well suited for the task.

Macro scripts

Macro scripts are scripts created with the Macro Recorder. Any script associated with a toolbar button is considered a Macro script. Max organizes Macro scripts by their category, which you can change by editing the script file. To call a Macro script from another script, you can use the macros command. For example,

macros.run “objects” “sphere”

runs the “sphere” script in the “objects” category.

Macro scripts generally require no other user input; you just click a button, and the script works its magic.

Scripted utilities

A scripted utility is a MAXScript that has its own custom rollout in the Utilities panel, like the SphereArray example. This type of script is particularly useful when your script has parameters that the user needs to enter, such as the radius in the SphereArray script. Scripted utilities are easy to build using the Visual MAXScript Editor.

Scripted right-click menus

When you right-click an object in your scene, Max opens a pop-up menu of options for you to choose from, much like a quadmenu. Scripted right-click menus let you append your own menu items to the right-click menu. If you create a script that modifies some property of an object, making the script available through the right-click menu makes it easily accessible.

Scripted mouse tools

You can use scripted mouse tools to create scripts that handle mouse input in the viewports. These scripts listen for commands from the mouse, such as clicking the mouse buttons and clicking and dragging the cursor. For example, you would use this type of MAXScript if you were making a new primitive object type so that users could create the new objects just like they would a sphere or a box.

Scripted plug-ins

Scripted plug-ins are by far the most complex type of MAXScript available. They mirror the functionality of non–MAXScript plug-ins (which are written in other programming languages such as C++). You can create scripted plug-ins that make new geometry, create new shapes, control lights, act as modifiers, control texture maps and materials, and even produce special rendering effects.

Writing Your Own MAXScripts

This section presents the basics of the MAXScript language and shows you how to use the various parts of MAXScript in your own scripts. You can test any of these scripting commands using the MAXScript Listener window.

Cross-Reference

Much of the discussion that follows will sound familiar if you've already read the material on expressions found in Chapter 36, “Animating with the Expression Controller and Wiring Parameters.” Expressions use many of the same constructs as MAXScript.

Variables and data types

A variable in MAXScript is sort of like a variable in algebra. It represents some other value, and when you mention a variable in an equation, you're actually talking about the value that the variable holds. You can think of variables in MAXScript as containers that you can put stuff into and take it out of later. Unlike variables in algebra, however, variables in MAXScript can “hold” other things besides numbers, as you'll soon see.

To put a value into a variable, you use the equal sign. For example, if you type

X = 5 * 3

in the MAXScript Listener window, Max evaluates the expression on the right side of the equal sign and stores the result in the variable named X. In this case, Max would multiply 5 and 3 and would store the result (15) in X. You can then see what is in X by just typing X in the Listener window and pressing Enter. Max then displays the value stored in X, or 15.

You can name your variables whatever you want, and naming them something that helps you remember what each variable is for is a good idea. For example, if you want a variable that keeps track of how many objects you're going to manipulate, the name “objCount” would be better than something like “Z.”

Note

Variable names can be just about anything you want, but you must start a variable name with a letter. Also, the variable name can't have any special characters in it, like spaces, commas, or quotation marks. You can, however, use the underscore character and any normal alphabetic characters.

Variables can also hold strings, which are groups of characters. For example,

badDay = “Monday”

stores the word “Monday” in the variable badDay. You can attach two strings together using the plus sign, like this:

grouchy = “My least favorite day is” + badDay

Now the variable grouchy holds the value “My least favorite day is Monday.”

Try this:

wontWork = 5 + “cheese”

Max prints out an error because it's confused: You're asking it to add a number to a string. The problem is that 5 and “cheese” are two different data types. Data types are different classes of values that you can store in variables. You can almost always mix values of the same data type, but values of different types usually don't make sense together.

Note

To see the data type of a variable, use the classof command. Using the previous example, you could type classof grouchy, and Max would, in turn, print out String.

Another very common data type is Point3, which represents a three-dimensional point. Following are a few examples of using points, with explanatory comments:

Pos = [5,3,2]          -- Marks a point at (5,3,2)
Pos.x = 7              -- Change the x coordinate to 7
                       -- Now the point is at (7,3,2)
Pos = Pos + (1,2,5)    -- Take the old value for Pos,
                       -- move it by (1,2,5) to (8,5,7)
                       -- and store the new value in Pos

In addition to these basic data types, each object in your scene has its own data type. For example, if you use classof on a sphere object, Max prints out Sphere. Data types for scene objects are actually complex data types or structures, which means that they are groups of other data types in a single unit. The pieces of data inside a larger object are called members or properties. Most scene objects have a member called Name, which is of type String. The Name member tells the specific name of that object. Another common property is Position, a Point3 variable that tells the object's position.

Max has a special built-in variable that represents whatever object is currently selected. This variable is $ (the dollar sign), which is used in the following tutorial.

Tutorial: Using variables

In this tutorial, you learn more about variables in MAXScript by using them to manipulate an object in your scene.

To use variables to manipulate scene objects, follow these steps:

  1. Open the Teapot.max file from the Bonus Chapter 21 directory on the CD.

    This file has a simple teapot object.

  2. Right-click on the title for the Left viewport, and choose Views image Extended image MAXScript Listener to open the MAXScript Listener window in the Left viewport.
  3. Select the teapot object, type $, and press Enter.

    Max displays information about the teapot. (Your numbers will probably be different depending on where you placed your teapot.)

  4. Type the following lines one at a time in the top pane to see the property values stored as part of the teapot object:
    $.position
    $.wirecolor
    $.radius
    $.name
    $.lid
  5. Now type these lines, one at a time, to set the property values of the teapot object:
    $.lid = false
    $.position.x = −20
    $.segs = 20

Figure 13 shows the commands, their results in the MAXScript Listener window, and the resulting teapot object.

FIGURE 13 The script commands entered in the MAXScript Listener affect the objects in the viewports.

image

Program flow and comments

In general, when Max begins executing a script, it starts with the first line of the script, processes it, and then moves on to the next line. Execution of the script continues until no more lines are in the script file. (Later, you'll look at some MAXScript keywords that let you change the flow of script execution.)

Max lets you embed comments or notes in your script file to help explain what is happening. To insert a comment, precede it with two hyphens (--). When Max encounters the double hyphen, it skips the comment and everything else on that line and moves to the next line of the script. For example, in this line of MAXScript

$Torus01.pos = [0,0,0] -- Move it back to the origin

Max processes the first part of the line (and moves the object to the origin) and then moves on to the next line after it reaches the comment.

Using comments in your MAXScript files is very important because as your scripts start to become complex, figuring out what is happening can get difficult. Also, when you come back a few months later to improve your script, comments will refresh your memory and help keep you from repeating the same mistakes you made the first time around.

Note

Because Max ignores anything after the double hyphen, you can use comments to temporarily remove MAXScript lines from your script. If something isn't working right, you can comment out the lines that you want Max to skip. Later, when you want to add them back in, you don't have to retype them. You can just remove the comment marks, and your script is back to normal.

Expressions

An expression is what Max uses to make decisions. An expression compares two things and draws a simple conclusion based on that comparison.

Cross-Reference

These same expressions can be used within the Expression controller. You can find details on this controller in Chapter 36, “Animating with the Expression Controller and Wiring Parameters.”

Simple expressions

The expression

1 < 2

is a simple expression that asks the question, “Is 1 less than 2?” Expressions always ask yes/no type questions. When you type an expression in the MAXScript Listener window (or inside of a script), Max evaluates the expression and prints true if the expression is valid (like the preceding example) and false if it isn't. Try the following expressions in the Listener window, and Max will print the results as shown in Figure 14 (you don't have to type in the comments):

1 < 2           -- 1 IS less than 2, so expression is true
1 > 2           -- 1 is NOT greater than 2, so false
2 + 2 == 4      -- ‘==’ means “is equal to”. 2 + 2 is
                -- equal to 4, so true
2 + 2 == 5      -- 4 is NOT equal to 5, so false
3 * 3 == 5 + 4  -- 9 IS equal to 9, so true

3 * 3 != 5 + 4  -- ‘!=’ means ‘not equal to'. ‘9 is not
                -- equal to 9’ is a false statment, so
                -- the expression is false

a = 23          -- store 23 in variable a
b = 14 + 9      -- store 23 in variable b
a == b          -- 23 IS equal to 23, so true

Play around with simple expressions until you're familiar with what they mean and have an intuitive feel for whether or not an expression is going to evaluate to true or false.

FIGURE 14 Using the MAXScript Listener to evaluate expressions

image

Complex expressions

Sometimes you need an expression to decide on more than just two pieces of data. MAXScript has the and, or, and not operators to help you do this.

The and operator combines two expressions and asks the question, “Are both expressions true?” If both are true, then the entire expression evaluates to true. But if either is false, or if they are both false, then the entire expression is false. You can use parentheses to group expressions, so an expression with the and operator might look something like this:

(1 < 2) and (1 < 3)    -- true because (1 < 2) is true AND
                       -- (1 < 3) is true

The or operator is similar to and, except that an expression with or is true if either of the expressions is true or if both are true. Here are some examples:

(2 > 3) or (2 > 1)      -- even though (2 > 3) is false, the
                        -- entire expression is true because
                        -- (2 > 1) is true
(2 > 3) and (2 > 1)     -- false because both expressions are
                        -- not true

Try some of these complex expressions to make sure that you understand how they work:

a = 3
b = 2
(a == b) or (a > b)    -- true because a IS greater than b
(a == b) and (b == 2)  -- false because both expressions are
-- not true
 (a > b) or (a < b)     -- true because at least one IS true
(a != b) and (b == 3)  -- false because b is NOT equal to 3

The not operator negates or flips the value of an expression from true to false, or vice versa. For example:

(1 == 2)               -- false because 1 is NOT equal to 2
not (1 == 2)           -- true. ‘not’ flips the false to true

Conditions

Conditions are one way in which you can control program flow in a script. Normally, Max processes each line, no matter what, and then quits; but with conditions, Max executes certain lines only if an expression is true.

For example, suppose you have a script with the following lines:

a = 4
If (a == 5) then
(
 b = 2
)

Max would not execute the line b = 2 because the expression (a == 5) evaluates to false. Conditional statements, or “if” statements, basically say, “If this expression evaluates to true, then do the stuff inside the block of parentheses. If the expression evaluates to false, skip those lines of script.”

Conditional statements follow this form:

If <expr> then <stuff>

where <expr> is an expression to evaluate and <stuff> is some MAXScript to execute if the expression evaluates to true. You can also use the keyword else to specify what happens if the expression evaluates to false, as shown in the following example:

a = 4
if (a == 5) then
(
 b = 2
)
else
(
 b = 3
)

After this block of MAXScript, the variable b would have the value of 3 because the expression (a == 5) evaluated to false. Consequently, Max executed the MAXScript in the else section of the statement.

Collections and arrays

MAXScript has some very useful features to help you manipulate groups of objects. A group of objects is called a collection. You can think of a collection as a bag that holds a bunch of objects or variables. The things in the bag are in no particular order; they're just grouped together.

You can use collections to work with groups of a particular type of object. For example, the MAXScript

a = $pokey*
a.wirecolor = red

creates a collection that contains every object in your scene whose name starts with “Pokey” and makes every object in that collection turn red.

MAXScript has several built-in collections that you might find useful, such as cameras and lights, containing all the cameras and lights in your scene. So

delete lights

removes all the light objects from your scene (which may or may not be a good idea).

An array is a type of collection in which all the objects are in a fixed order, and you can access each member of the array by an index. For example

a = #()     -- creates an empty array to use
a[1] = 5
a[2] = 10
a[5] = 12
a

After the last line, Max prints out the current value for the array:

#(5, 10, undefined, undefined, 12)

Notice that Max makes the array big enough to hold however many elements you want to put in it, and that if you don't put anything in one of the positions, Max automatically puts in undefined, which simply means that array location has no value at all.

One last useful trick is that Max lets you use the as keyword to convert from a collection to an array:

LightArray = (lights as array)

Max takes the built-in collection of lights, converts it to an array, and names the array LightArray.

The members of an array or a collection don't all have to have the same data type, so it's completely valid to have an array with numbers, strings, and objects, like this:

A = #(5, “Mr. Nutty”, box radius:5)

Note

You can use the as MAXScript keyword to convert between data types. For example, (5 as string) converts the number 5 to the string “5,” and (5 as float) converts the whole number 5 to the floating-point number 5.0.

Loops

A loop is a MAXScript construct that lets you override the normal flow of execution. Instead of processing each line in your script once and then quitting, Max can use loops to do something several times.

For example,

j = 0
for i = 1 to 5 do
(
 j = j + i
)

This MAXScript uses two variables—i and j—but you can use any variables you want in your loops. The script sets the variable j to 0 and then uses the variable i to count from 1 to 5. Max repeats the code between the parentheses five times, and each time the variable i is incremented by 1. Inside the loop, Max adds the current value of i to j. Can you figure out what the value of j is at the end of the script? If you guessed 15, you're right. To see why, look at the value of each variable as the script is running:

When                  j     i
----------------------------
First line            0     0
Start of loop         0     1
After first loop      1     1
Start of second loop  1     2
After second loop     3     2
Start of third loop   3     3
After third loop      6     3
Start of fourth loop  6     4
After fourth loop     10    4
Start of fifth loop   10    5
After fifth loop      15    5

A loop is also useful for processing each member of an array or collection. The following MAXScript shows one way to turn every teapot in a scene blue:

teapots = $teapot*             -- get the collection of teapots
for singleTeapot in teapots do
(
 singleTeapot.wirecolor = blue
)

You can use a for loop to create a bunch of objects for you. Try this MAXScript:

for I = 1 to 10 collect
 (
 sphere radius:15
)

The collect keyword tells Max to create a collection with the results of the MAXScript in the block of code inside the parentheses. The line

sphere radius:15

tells Max to create a sphere with radius of 15, so the entire script created 10 spheres and added them to your scene. Unfortunately, Max puts them all in the same spot, so move them around a bit so you can see them:

i = −50
For s in spheres do
(
 s.position = [i,i,i]
 i = i + 10
)

Study this script to make sure that you understand what's going on. You use a for loop to process each sphere in your collection of spheres. For each one, you set its position to [i,i,i], and then you change the value of i so that the next sphere is at a different location.

Functions

The last feature of basic MAXScript that you'll look at is the function. Functions are small chunks of MAXScript that act like program building blocks. For example, suppose that you need to compute the average of a collection of numbers many times during a script you're writing. The MAXScript to do this might be:

Total = 0
Count = 0
For n in numbers do
(
 total = total + n
 count = count + 1
)
average = total / (count as float)

Given a collection of numbers called numbers, this MAXScript computes the average. Unfortunately, every time you need to compute the average, you have to type all that MAXScript again. Or you might be smart and just cut and paste it in each time you need it. Still, your script is quickly becoming large and ugly, and you always have to change the script to match the name of your collection you're averaging.

A function solves your problem. At the beginning of your script, you can define an average function like this:

Function average numbers =
( -- Function to average the numbers in a collection
 local Total = 0
 local Count = 0
 For n in numbers do
 (
 total = total + n
 count = count + 1
 )
 total / (count as float)
)

Now any time you need to average any collection of numbers in your script, you could just use this to take all the numbers in the collection called num and store their average in a variable called Ave:

Ave = average num -- assuming num is a collection

Not only does this make your script much shorter if you need to average numbers often, but it makes it much more readable, too. It's very clear to the casual reader that you're going to average some numbers. Also, if you later realize that you wrote the average function incorrectly, you can just fix it at the top of the script. If you weren't using functions, you would have to go through your script and find every case where you averaged numbers and then fix the problem. (What a headache!)

Now take another look at the function definition. The first line

Function average numbers =

tells Max that you're creating a new function called average. It also tells Max that to use this function, you have to pass in one piece of data, and that inside the function you refer to that data using a variable called numbers. It doesn't matter what the name of the actual variable was when the function was called; inside the function, you can simply refer to it as numbers.

Creating functions that use multiple pieces of data is also easy. For example,

Function multEm a b c = (a * b * c)

creates a function that multiplies three numbers together. To use this function to multiply three numbers and store the result in a variable called B, you would simply enter

B = multEm 2 3 4

The next two lines

local Total = 0
local Count = 0

create two variables and set them both to 0. The local keyword tells Max that the variable belongs to this function. No part of the script outside of the function can see this variable, and if there is a variable outside the function with the same name, changing the variable inside this function won't affect that variable outside the function. That way, you never have to worry about what other variables are in use when someone calls average; even if variables are in use that are named Total or Count, they won't be affected.

The last line

total / (count as float)

uses the Total and Count values to compute the average. How does that value get sent back to whoever called the function? Max evaluates all the MAXScript inside the function and returns the result. Because the last line is the last thing to be evaluated, Max uses the result of that calculation as the result of the entire function.

Tutorial: Creating a school of fish

Let's look at an example that puts into practice some of the things you've learned in this chapter. In this multipart tutorial, you use MAXScript to create a small school of fish that follows the dummy object around a path.

Part 1: Making the fish follow a path

In this part of the tutorial, you use MAXScript to move one of the fish along a path in the scene. To do this, follow these steps:

  1. Open the Fish scene.max file from the Bonus Chapter 21 directory on the CD.

    This scene consists of two fish and a dummy object that follows a path. What you need to do is use MAXScript to create a small school of fish that follows the dummy object around the path.

  2. Press F11 to open the MAXScript Listener window. In the window, choose File image New Script to open the MAXScript Editor window, and type the following script:
    pathObj = $Dummy01
    fishObj = $Fish1/FishBody
    relPos = [0,-150,-50] -- How close the fish is to the path
    
    
    animate on
    (
    for t = 1 to 100 do at time t
    (
    fishObj.position = pathObj.position + relPos
    )
    )
  3. Select the Camera01 viewport. Choose Tools image Evaluate All (or press Ctrl+E) to evaluate all the MAXScript in the Editor window, right-click the Camera01 viewport to activate it, and click the Play Animation button.

    The fish rigidly follows the dummy object's path. Figure 15 shows one frame of this animation.

FIGURE 15 First attempt at making the fish follow a path

image

Now you'll explain the MAXScript entered in the previous tutorial. The first few lines create some variables that the rest of the script uses. pathObj tells the name of the object that the fish will follow, and fishObj is the name of the fish's body. (Notice that you can reference parts of the group hierarchy by using the object name, a forward slash, and then a child part.) Why bother creating a variable for the fish object? After you get this first fish working, you want to apply the same script to another fish. All you have to do is rename Fish1 as Fish2, re-execute the script, and you're finished!

The script also creates a variable called relPos, which you use to refer to the relative position of the fish with respect to the dummy object. If you have several fish in the scene, you don't want them all in the exact same spot, so this is an easy way to position each one.

The next block of MAXScript is new: You're using the animate on construct. This tells Max to generate keyframes for your animation. It's the same as if you had pressed Max's Animation button, run our script, and then shut Animation off. So any MAXScript inside the animate on parentheses creates animation keyframes. These parentheses define a section of the script you call a block.

Inside the animation block, you have a loop that counts from 1 to 100 (corresponding to each frame of our animation). On the end of the loop line, you have at time t, which tells Max that for each time through the loop, you want all the variables to have whatever values they'll have at that time. For example, if you want the fish to follow the dummy object, you have to know the position of the object at each point in time instead of just at the beginning; so each time through the loop, Max figures out for you where the dummy object will be.

Inside the loop, you set the fish's object to be that of the dummy object (at that point in time) and then adjust the fish's position by relPos.

Part 2: Adding body rotation and tail animation

Next you'll make that fish look a little more lifelike by animating its tail and having it rotate its body to actually follow the path. Also, you'll add a little unpredictability to its motion so that when you add other fish, they aren't exact copies of each other.

To improve the fish's animation, follow these steps:

  1. Type the revised version of the script (the new lines are in bold):
    pathObj = $Dummy01
    fishObj = $Fish1/FishBody
    fishTail = $Fish1/FishBody/FishTail
    relPos = [0,-150,-50]  -- How close the fish is to the path
    
    fishTail.bend.axis = 0 -- 0 is the x-axis
    zadd = 4               -- vertical movement at each step
    tailFlapOffset = (random 0 100)
    tailFlapRate = 25 + (random 0 25)
    animate on
    (
     for t = 0 to 100 do at time t
     (
      fishObj.position = pathObj.position + relPos
    fishObj.position.z = relPos.z
    relPos.z += zadd
    
    -- let's say that there's a 10% chance that the fish will
    -- change directions vertically
    if ((random 1 100) > 90) then
    (
    zadd = -zadd
    )
    
    fishTail.bend.angle = 50 * sin (t * tailFlapRate +
    tailFlapOffset)
    
    oldRt = fishObj.rotation.z_rotation
    newRt = (in coordsys pathObj pathObj.rotation.z_rotation)
    
    if ((random 1 100) > 85) then
    (
    fishObj.rotation.z_rotation += (newRt - oldRt) *
    (random 0.5 1.5)
    )
    )
    )
  2. Save your script (File image Save), and then press Ctrl+E to evaluate the script again. This script is saved in the Bonus Chapter 21 directory as FishPath2.ms. Make the Camera01 viewport active, and click Play Animation. Figure 16 shows another frame of the animation. As you can see, the fish is heading in the right direction this time, and the tail is flapping wildly.

FIGURE 16 A tail-flapping fish that faces the right direction as it follows the path

image

Okay, look at what changed. First, you added a variable to refer to the fish's tail, so that it is easy to change when you add another fish. Also, you accessed the bend modifier of the tail and set its axis to 0, which corresponds to the X-axis. (You can try other values to see that it really does change the axis parameter in the rollout.)

Next, you created some more variables. You use zadd to tell Max how much to move the fish in the Z-direction at each step. (You don't want our fish to always swim at the same level.) tailFlapOffset and tailFlapRate are two variables used to control the tail flapping. (I explain this when you get to the part of the script that uses them.)

Inside the for loop, notice that you've overridden the fish's Z-position and replaced it with just the relative Z-position, so that each fish swims at its own depth and not the dummy object's depth. Then, at each step, you add zadd to the Z-position so that the fish changes depth slowly. You have to be careful, or your fish will continue to climb out of the scene or run into the ground, so at each step you also choose a random number between 1 and 100 with the function (random 1 100). If the random number that Max picks is greater than 90, you flip the sign of zadd so that the fish starts moving in the other direction. This is a fancy way of saying, “There's a 90 percent chance that the fish will continue moving in the same direction and a 10 percent chance that it will switch directions.”

In the next part, you again access the tail's bend modifier, this time to set the bend angle. To get a nice back-and-forth motion for the tail, you use the sin function. In case you've forgotten all that math from when you were in school, a sine wave oscillates from 1 to –1 to 1 over and over again. By multiplying the function by 50, you get values that oscillate between 50 and –50 (pretty good values to use for your bend angle). You use tailFlapOffset to shift the sine wave so that the tail flapping of additional fish is out of synch slightly with this one (remember, you're trying to get at least a little realism here) and tailFlapRate to make each fish flap its tail at a slightly different speed.

The only thing left for you to do is to make the fish “follow” the path; that is, rotate its body so that it's facing the direction it's moving. The simplest way to do this is to use the following MAXScript (split into two lines to make it easier to read):

newRt = (in coordsys pathObj pathObj.rotation.z_rotation)
fishObj.rotation.z_rotation = newRt

The in coordsys construct tells Max to give you a value from the point of view of a particular coordinate system. Instead of pathObj, you could have asked for the Z-rotation in the world, local, screen, or parent coordinate system, too. In this case, you want to rotate the fish in the same coordinate system as the dummy object. To randomize the direction of the fish a little, you've made the rotation a little more complex:

oldRt = fishObj.rotation.z_rotation
newRt = (in coordsys pathObj pathObj.rotation.z_rotation)

if ((random 1 100) > 85) then
(
 fishObj.rotation.z_rotation += (newRt - oldRt) *
                                     (random 0.5 1.5)
)

First, you save the old Z-rotation in oldRt, and then you put the new rotation in newRt. Again, you pick a random number to decide whether you'll do something; in this case you're saying, “There's an 85 percent chance I won't change directions at all.” If your random number does fall in that other 15 percent, however, you adjust the fish's rotation a little. You take the difference between the new rotation and the old rotation and multiply it by a random number between 0.5 and 1.5, which means you adjust the rotation by anywhere from 50 percent to 150 percent of the difference between the two rotations. So any fish will basically follow the same path, but with a little variation here and there.

Note

Max lets you use shorthand when adjusting the values of variables. Instead of saying a = a + b, you can just say a += b. Both have the same effect.

Part 3: Animating the second fish

This scene actually has two fish in it (the other one has been sitting patiently off to the side), so for the final part of this tutorial, you get both fish involved in the animation. To animate the second fish alongside the first one, follow these steps:

  1. At the top of the script, change these three lines (changes are in bold):
    pathObj = $Dummy01
    fishObj = $Fish2/FishBody
    fishTail = $Fish2/FishBody/FishTail
    relPos = [50,75,0] -- How close the fish is to the path
  2. Choose Tools image Evaluate All (or press Ctrl+E) to run the script again, and then animate it. Figure 17 shows both fish swimming merrily.

FIGURE 17 Both fish swimming together

image

This script generates keyframes for the second fish because you changed the fishObj and fishTail variables to refer to the second fish. You've also moved the second fish's relative position so that the two don't run into each other.

Learning the Visual MAXScript Editor Interface

Building scripts can be complicated, and piecing together a rollout for a scripted utility can be especially time-consuming and frustrating when done by hand. To help create such custom rollouts, Max includes the Visual MAXScript Editor. Using this editor, you can drag and drop rollout elements and automatically create a code skeleton for certain events.

Working with textual commands can be time-consuming. In order for the script to work, you need to enter the commands exactly. This can be especially tricky when you're trying to lay out the controls for a rollout. The Visual MAXScript Editor speeds up the creation of rollouts.

To access the Visual MAXScript window, shown in Figure 18, select it from the MAXScript menu. Another way to access this window is to select Edit image New Rollout or Edit Rollout (F2) in the MAXScript Editor window.

FIGURE 18 The Visual MAXScript window makes building rollouts easy.

image

Layouts for a rollout created in the Visual MAXScript window can be saved as files with the .vms extension using the File menu. If you access the window from a MAXScript Editor window, then the Save menu automatically updates the editor window.

The Editor interface

The window includes two major panes. The left pane is where the various rollout elements are assembled, and the right pane holds the Value and Event Handlers tabbed panels. The Value panel lists all the properties and their associated values for the selected element. You can change the property values by clicking on them and entering a new value. For example, if you select a Button element in the left panel, then the properties for that control are presented in the Value panel. If you click the Caption Property, its value becomes highlighted; you can type a new caption, and the new caption appears on the button.

The Event Handlers panel lists all the available events that can be associated with the selected element. Clicking the check box to the left of these events can enable the events. For a button element, you can enable the pressed event. With this event enabled, the code includes a function where you can define what happens when this event is fired.

The menus and the main toolbar

At the top of the interface are some menu options and a main toolbar. The File menu also lets you create a new layout (Ctrl+N), save layouts to a file (Ctrl+S), and open saved layouts (Ctrl+O). The Edit menu allows you to cut (Ctrl+X), copy (Ctrl+C), and paste (Ctrl+V) form elements. You can find these same features as buttons on the top toolbar.

The Layout menu includes options for aligning elements left (Ctrl+left arrow), right (Ctrl+right arrow), top (Ctrl+up arrow), bottom (Ctrl+down arrow), vertical center (F9), and horizontal center (Shift+F9); to space elements evenly across (Alt+right arrow) or down (Alt+up arrow); make elements the same size by width, height, or both; center vertically (Ctrl+F9) or horizontally (Ctrl+Shift+F9) in the dialog box; and flip. You can use the Layout image Guide Settings menu command to specify grid snapping and spacing. Grids are enabled using the Toggle Grid/Snap button on the right end of the main toolbar.

You can also access these commands using a right-click pop-up menu when clicking on the left pane.

Toolbar elements

The toolbar along the bottom of the window contains the form elements that you can drop on the form. These buttons and elements include those shown in Table 2.

TABLE 2 Visual MAXScript Form Elements

image

image

At the bottom right of the window are two text fields that display the coordinates of the current mouse cursor position and the size of the rollout. The default size of the rollout is 162×300, which is the size needed to fit perfectly in the Command Panel.

Laying Out a Rollout

The rollout space, which appears gray in the left pane, can be selected and resized by dragging the black, square handles at the edges of the form. As you change its size, its dimensions are displayed in the lower-right corner of the interface. With the rollout space correctly sized, you are ready to add elements to the space.

To add one of these elements to the form, click the element button on the toolbar and drag on the form. The element appears and is selected. The selected element is easy to identify by the black handles that surround it. Dragging on these handles resizes the element, and clicking and dragging on the center of the element repositions it within the rollout space.

The Value and Events panels are automatically updated to show the values and events for the selected element. Values such as width and x-pos are automatically updated if you drag an element or drag its handles to resize it.

Aligning and spacing elements

Although only one element at a time can be surrounded by black handles, you can actually drag an outline in the rollout space to select multiple elements at once. With several elements selected, you can align them all to the left (Ctlr+left arrow), horizontally centered (Shift+F9), right (Ctrl+right arrow), top (Ctrl+up arrow), vertically centered (F9), or bottom (Ctrl+down arrow).

Multiple elements can also be spaced across (Alt+right arrow) or down (Alt+up arrow). To make several elements the same width, height, or both, use the Layout image Make Same Size menu command. The Center in Dialog menu aligns elements to the center of the dialog box either vertically (Ctrl+F9) or horizontally (Ctrl+Shift+F9). The Flip command reverses the position of the selected elements.

Figure 19 shows a form with several aligned elements added to it.

FIGURE 19 You can add control elements to the form in the Visual MAXScript window.

image

Tutorial: Building a custom rollout with the Visual MAXScript Editor

Now you need some practice using this powerful tool. In this example, you use the Visual MAXScript window to lay out a rollout and code the script to make it work.

To create a custom rollout using the Visual MAXScript Editor, follow these steps:

  1. Open the BuildCube.max file from the Bonus Chapter 21 directory on the CD.

    This file includes a simple sphere object.

  2. Choose MAXScript image New Script to open the MAXScript Editor window. In the editor window, enter the following:
    utility buildCube “Build Cube” ( )

    This line creates a utility named buildCube. The rollout name is Build Cube. Make sure to include a space in between the parentheses.

  3. Choose Tools image New Rollout from the window menu (or press the F2 key). The Visual MAXScript window opens. The properties for this rollout are displayed in the Properties panel. Drag the lower-right, black square handle to resize the rollout form.
  4. Click the spinner button on the bottom toolbar, and drag in the rollout form to create a spinner element. In the Properties panel, set the name to SideNum, set the caption value to No. of Side Objects, select the type, and set the range to [1,100,5]. The range values set the lower, upper, and default values for the spinner. Then drag the element handles to resize the element to fit in the form.
  5. Click the spinner button again, and drag in the rollout form to create another spinner element. In the Properties panel, set the name to length, set the caption value to Side Length, select the type, and set the range to [1,1000,50]. Then drag the element handles to resize the element to fit in the form.
  6. Click the button icon on the bottom toolbar, and drag in the rollout form to create a button below the spinners. In the Properties panel, set the name to createCube and the caption value to Create Cube. Then drag the element handles to resize the button so the text fits on the button. Open the Event Handlers panel, and select the Pressed check box.
  7. Drag over the top of both the spinners to select them both, and choose Layout image Align image Right (or press Ctrl+right arrow) to align the spinners. Figure 20 shows how the rollout layout looks.
  8. With the layout complete, choose File image Save (or press Ctrl+S) to save the layout, and then close the Visual MAXScript window.

    The script code associated with the layout is automatically placed in the editor window.

  9. Complete the script by entering the script commands immediately after the open parenthesis that appears on the line following the on createCube pressed do event, as shown in Figure 21. Then, copy and paste the code from the BuildCube.ms file from the Bonus Chapter 21 directory on the CD.
  10. Open the Utilities panel, and click the MAXScript button. Then click the Run Script button, and select the BuildCube.ms file from the Bonus Chapter 21 directory on the CD.

    The utility installs and appears in the Utility drop-down list in the MAXScript rollout.

  11. Select the BuildCube utility from the drop-down list in the MAXScript rollout, and scroll down the Command Panel to see the Build Cube rollout. Select the sphere object, and click the Create Cube button.

    The script executes, and a cube of spheres is created.

FIGURE 20 The rollout laid out in the Visual MAXScript window

image

FIGURE 21 The MAXScript Editor window is updated with the code from the Visual MAXScript window.

image

Figure 22 shows the results of the BuildCube.ms script. You can use this script with any selected object.

FIGURE 22 The results of the BuildCube.ms script

image

Summary

This chapter gave you a brief introduction to MAXScript, 3ds Max's powerful, built-in scripting language. Besides describing the different types of scripts you can create, the chapter covered the following topics:

  • The basics of MAXScript
  • Using the MAXScript tools such as the MAXScript Editor and Listener windows
  • Using the Macro Recorder to create scripts
  • Using the MAXScript Debugger
  • The different script types
  • The basics of writing your own scripts
  • The Visual MAXScript Editor interface
  • The features of each rollout element
  • How to create scripted utilities with custom rollouts
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.202.209