dubs maxscript tutorials

Upload: adam-ambrus

Post on 03-Jun-2018

221 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/12/2019 Dubs Maxscript Tutorials

    1/42

  • 8/12/2019 Dubs Maxscript Tutorials

    2/42

  • 8/12/2019 Dubs Maxscript Tutorials

    3/42

    D U B M A X S C R I P T T U T O R I A L S

    Part 1 The basics the

    very basics

    This tutorial should take around 5 minutes to complete

    will hopefully do a few of these over the next while. I'll start off really really basicfor those who have always wanted to learn maxscript but haven't been able to getstarted. (That was me for a long time)

    The best way to learn maxscript is to learn a few basic tricks that you can use in youreveryday work. You can then extend your knowledge as you come across tasks thatyou can *almost do with your current knowledge.

    IntroOk, first of all I'll go over a few basics.To follow along with these tuts, open the maxscript listener byhitting F11.

    The pink area up the top is the listener where if you enable the macrorecorder, it willtell you what max is doing in maxscript terms as you do regular tasks in max. We won'tpay attention to this area in this tut.

    The white area is where everything will be happening. Delete the "Welcome tomaxscript" message so we have a blank slate to start with..

    Chapter

    1

    I

  • 8/12/2019 Dubs Maxscript Tutorials

    4/42

    D U B M A X S C R I P T T U T O R I A L S

    The basics

    Create a sphere in the scene so we have an object to talk to.

    There are two simple ways to refer to an existing scene object in max. You can select it and refer tothe selection or you can refer to it by name. The way maxscript refers to objects is by their namewith a $ in front. So to refer to the sphere you just created, type:

    $Sphere01Now, with the cursor at the end of that, hit the enter on the numeric keypad. That will execute thecurrent line. If you want to execute more than one line, select them all and hit numeric enter.

    once you hit enter, maxscript will return the following in blue:$Sphere:Sphere01@ [10,-5,0]

    The last numbers will vary depending on where you created the sphere in the scene.This is confirmation that you are talking about the sphere and that your syntax is correct.

    Object Attributes

    Now lets try something slightly more useful. Type:

    $Sphere01.radius

    and hit numeric enter to execute. maxscript will return the radius of the sphere!Notice how there is a hierarchy to the command. You started with the object itself then a period (.)then the parameter belonging to the object. You can refer to other parameters the same way. ie;

    $Sphere01.segments will return the segments value.

    Setting attribute values

    Now what we want to do is change the values not just look at them.

    Simply type:

    $Sphere01.segments = 35

    You'll notice as soon as you execute the line, the sphere changes it's segments to 35!Well you could have done that faster with the GUI right? What if you have 25 spheres all withdifferent radii and you want to just change their segment count? (a common problem)

  • 8/12/2019 Dubs Maxscript Tutorials

    5/42

    D U B M A X S C R I P T T U T O R I A L S

    Working on selections of many objects

    I referred earlier to the fact we can refer to objects by referring to the current selection. Inmaxscript the shortcut to this is to simply select an object (select your sphere) and type:

    $

    When you execute this, you'll get the same result as if you had typed $Sphere01Now we are going to exploit the power of "mapped functions"

    Create 10 spheres of random radii and position. Select them all. Now type the following andexecute it:

    $.segments = 10

    All the spheres will retain all their setting except the segments on all of them will be set to 10.Thats it for now!

    Conclusion

    Play around with other objects and other attributes.if you want to know what parameters are availiable to you on a given object, type:

    showproperties $

    For the sphere, that will return the following list:

    .smooth : boolean

    .radius : float

    .segs : integer

    .mapcoords : boolean

    .slice : boolean

    .hemisphere : float

    .sliceFrom : angle

    .sliceTo : angle

    .chop : integer

    .recenter : boolean.realWorldMapSize : booleanfalse

  • 8/12/2019 Dubs Maxscript Tutorials

    6/42

  • 8/12/2019 Dubs Maxscript Tutorials

    7/42

    D U B S M A X S C R I P T T U T O R I A L S

    Variables

    You can think of variables in MXS (maxscript) as a temporary named storage place for an "object"of some sort. think of them like lockers at the swimming pool. there are a huge number of them

    available (unlimited) and they all have nothing in them and are unnamed. Once you put somethingin a locker (variable) - it might be a number, a piece of text or even a modifier - and give it a name itwill always be in there until you replace it with something else.

    To set a variable in maxscript you simply type the following:

    variableName = variableValue

    The variable name can be anything you like and the value can be almost anything as well. For nowwe will use a float which is a number with a decimal place

    ourVariable = 34.5

    if you enter that into the listener and execute it, it will return 34.5now if you type an expression such as:

    2 * ourVariable

    Maxscript will return 69.0

    The main data types in maxscript are the following:

    Float - these are numbers will a decimal component to them ie 234.643Integer - These numbers are whole numbers only ie 5 or 200Boolean - true or falseString - this is a piece of text. To set a string you need to enclose it in quote marks ie:

    myStringVariable = "Maxscript sure is handy"

    One last thing. You can convert different data types from one to another like this:

    "35" as integer

    the 35 is a string (because it has quote marks around it) but the "as integer" after it, turns it into an

    integer. Obviously "as string" and "as float" do as you would expect.

  • 8/12/2019 Dubs Maxscript Tutorials

    8/42

    D U B S M A X S C R I P T T U T O R I A L S

    Loops

    Loops are where maxscript becomes really powerful and useful. They enable maxscript to dorepetitive tasks rather than you and the mouse.

    Imagine you have built a scene with many objects. You have added a turbosmooth modifier toall the objects with an iteration value of 2. This is now causing you problems because the sceneis too slow to navigate and you wish you had set the iterations to 1 with a rendertime setting of2.

    Here is the code:

    for obj in $ do(obj.modifiers[#turbosmooth].iterations = 1

    obj.modifiers[#turbosmooth].useRenderIterations = trueobj.modifiers[#turbosmooth].renderIterations = 2)

    We will now look at it line by line.

    for obj in $ do - Our for loop is saying in plain English: "For the objects in our currentselection, do the commands inside the following brackets."

    ( - We open the bracketsobj.modifiers[#turbosmooth].iterations = 1 - we set the iterations to 1

    obj.modifiers[#turbosmooth].useRenderIterations = trueobj.modifiers[#turbosmooth].renderIterations = 2 - these lines should be obvious to you bynow.

    ) - We close the brackets to end the for loop.

    Max will keep looping through the code on every object in the selection until it has done themall.

    You can test the code by making a bunch of objects all with turbosmooth on them. THEYMUST ALL HAVE A TURBOSMOOTH MODIFIER. if one object doesn't have a

    turbosmooth modifier, when MXS tries to talk to it, it won't find it and your script will fail withan error. This obviously isn't very satisfactory.

  • 8/12/2019 Dubs Maxscript Tutorials

    9/42

    D U B S M A X S C R I P T U T O R I A L S

    Comparison operators

    We can solve this problem by adding an "If" statement to the code

    But first of all we'll look at some comparison operators. if we have two items such as thenumbers 5 and 2, we can compare them in different ways try typing the following into thelistener:

    5 == 2-Is 5 equal to 2? -This returns False

    5 != 2-Is 5 NOT equal to 2? -This returns True

    5 < 2-Is 5 less than 2 -This returns False

    5 > 2-Is 5 greater than 2 -This returns True

    There are more as well which you'll find useful in due course.

    If Statements

    The way if works is like this:

    if (expression resulting in true or false) do(code goes here)

    Here is a sample which you should be able to read easily by now:

    if (obj.modifiers[#turbosmooth] != undefined) do(obj.modifiers[#turbosmooth].iterations = 1

    obj.modifiers[#turbosmooth].useRenderIterations = trueobj.modifiers[#turbosmooth].renderIterations = 2)

    That will check an object to make sure it has a turbosmooth modifier and then if it does, runthrough the code in the following brackets

  • 8/12/2019 Dubs Maxscript Tutorials

    10/42

    D U B S M A X S C R I P T U T O R I A L S

    Conclusion

    Now when we put it all together, we get the following script:

    for obj in $ do(if (obj.modifiers[#turbosmooth] != undefined) do(obj.modifiers[#turbosmooth].iterations = 1obj.modifiers[#turbosmooth].useRenderIterations = trueobj.modifiers[#turbosmooth].renderIterations = 2))

    It should happily run through every object in your current selection and if it has a turbosmooth

    modifier, set it to the values we specified..

  • 8/12/2019 Dubs Maxscript Tutorials

    11/42

    D U B S M A X S C R I P T U T O R I A L S

    Part 3 Making stuff

    random

    This tutorial should take around 10 minutes to complete

    or this tut, we'll have a look at the random function, object positioning and alsodo some more loops for practice.

    Intro

    Here is our hypothetical scenario. We want to build a fence across afield. We have made an array of tall boxes - 20 of them - for fenceposts unfortunately they look really uniform and CG like. What todo? Maxscript to the rescue..

    Chapter

    1

    F

  • 8/12/2019 Dubs Maxscript Tutorials

    12/42

    D U B S M A X S C R I P T U T O R I A L S

    The Random FunctionOpen the listener and type in the following command:

    random 1.0 35.0

    Maxscript will return a float number between 1 and 35. Notice how putting .0 after the numbermade maxscript realise that we wanted it to generate floats and not integers.

    Now we'll make a variable with a random integer between 1 and 6

    diceThrow = random 16

    Now whenever we access the diceThrow variable we made, it will contain the number that itrandomly chose when we first created the variable.

    Randomizing post heights

    Create an array of about 20 boxes. They should have their pivot on the ground and be 10 x 10 by100 high. Make the spacing about 150 units.

    I'm sure that you have a rough idea in your head by now of how we will go about this. Here is thecode:

    for obj in $ do(randHeight = random 90.0 110.0

    obj.height = randHeight)

    We have the same loop as last time. For all the objects in the selection, execute the following code:

    randHeight = random 90.0 110.0 - Make a variable with a random float between 90 and 110 in it.obj.height = randHeight - Assign that variable to the objects height.

    Select all your fencepost boxes and run the code. Now all the posts should have slightly differentheights!

  • 8/12/2019 Dubs Maxscript Tutorials

    13/42

    D U B S M A X S C R I P T T U T O R I A L S

    Position

    Create a sphere in the scene and select it.

    The way Maxscript accesses the position of objects is with the .position (or .pos) property.

    If you type:

    $.pos

    Maxscript should return: [12.3434,34.6446,0] or similar. You exact results will depend on whereyou made the sphere in your scene.

    Point Data typeThis result is a special type of data type called a Point3 data type. It contains X Y and Z valuesalways in that order. If we assign one to a variable:

    ourPoint3variable = [5,4,1]

    and then type this:

    ourPoint3variable.y

    Max will return 4 which is the Y component of our Point3. If we just type:

    ourPoint3variable

    Maxscript will return all the values - [5,4,1]Position (and many other things) in 3D often needs 3 values, X, Y and Z so a Point3 is a veryuseful data type.

    Moving ObjectsBack to setting an objects position.We could type the following:

    $.pos = [0,0,0]

    that will move our selected sphere to the center of the world. We are giving the sphere explicit co-ordinates to go to. What if we want to move it relative to where it is now?maxscript provides a move function to do just that.

  • 8/12/2019 Dubs Maxscript Tutorials

    14/42

    D U B S M A X S C R I P T T U T O R I A L S

    move $ [3,2,0]

    That is simply saying "Move the selected object +3 units in X, +2 units in Y and 0 units in Z"type:

    $.pos

    Now maxscript will return the position as [3,2,0]Execute the move line again:

    move $ [3,2,0]

    Then ask the position:

    $.pos

    You'll see that it is now at [6,4,0]Delete the sphere. (if you want to be fancy, type: delete $)

    Now we want to randomise the position of all the posts slightly.

    Randomizing Position

    Select all the posts again.

    Here is the code we are going to use.

    for obj in $ do(randX = random -5.0 5.0randY = random -5.0 5.0move obj [randX,randY,0])

    Lets step through it.For each object in our current selection do:Create a random float between -5 and 5 and assign it to the variable randXCreate a random float between -5 and 5 and assign it to the variable randY

    move the current object according to the following Point3. Where it says randX in the point3,maxscript will substitute in the random number it generated earlier. The same goes for the randY.we don't want the posts to move vertically so we have just put in a 0.

    Highlight the code and run it.

  • 8/12/2019 Dubs Maxscript Tutorials

    15/42

    D U B S M A X S C R I P T T U T O R I A L S

    ConclusionWe now have fence posts that vary randomly in height and x,y position. In the next tut, we'll alsorandomize their rotation so they all lean in slightly different directions.

    Save the max file as we'll use the same one next time.

  • 8/12/2019 Dubs Maxscript Tutorials

    16/42

    D U B S M A X S C R I P T T U T O R I A L S

    Part 4 More complex

    basics

    This tutorial should take around 10 minutes to complete

    Intro

    In this tut we'll be covering 4 things. Rotations,

    Comments, Saving and running scriptsand making macroscripts. Hopefully you still have yourmax file with the randomized fence posts from tut 3. Openit up.

    Chapter

    1

  • 8/12/2019 Dubs Maxscript Tutorials

    17/42

    D U B S M A X S C R I P T T U T O R I A L S

    Maxscript EditorFrom now on, we won't be running our main scripts from the listener. The listener is still usefulfor testing snippets of code before you incorporate it into your main script. Also you'll need tolook at the listener to see stuff returned from the maxscript parser.

    Click Maxscript>New Maxscript

    Hopefully a blank page should present itself. We will work in here from now on.

    Save your script. I suggest making two folders in your scripts folder. One for your randomsnippets of code that you've written for one-off tasks and the other for finished release qualityscripts with proper error checking, documentation and interfaces etc.

    Last time we finished with a script to randomly set the positions of the fencepost. Now we want tomodify the script so that we can randomly set their rotations.

    Rotations

    Rotations are slightly odd in Max in that we need to first create a "rotation object" that we willstore as a variable. Then we apply our rotation object to our object (a fencepost in this case!)

    As you possibly already know, in Max, there are 3 different types of rotations that you can use.Euler angles, Quaternions and Angleaxis. As you get more advanced, you will want to work withthe different types in different scenarios but for now, we will use euler angles.

    Eulerangles are defined in the following way: rot_obj = eulerangles x y z

    create a cube somewhere in your scene and type the following into the listener:

    cubeRotationObject = eulerangles 0 20 0

    Maxscript should return: (eulerAngles 0 20 0)

    Now we have our rotation object stored in our variable; cubeRotationObject.

    All we need to do now is apply the rotation object to our object. Select the cube and type thefollowing:

    rotate $ cubeRotationObject

    The cube should rotate 20 degrees around the Y axis.

  • 8/12/2019 Dubs Maxscript Tutorials

    18/42

  • 8/12/2019 Dubs Maxscript Tutorials

    19/42

    D U B S M A X S C R I P T T U T O R I A L S

    Macroscripts

    I'm now going to show you how to make your script into a macroscript that you can bind to ashortcut key or set as a menu option or button inside max.

    There is a function that we will be using strangely enough called macroscript. Here is a template:

    MacroScript Script_Name category:"Category Name" buttonText:"Name of Button orMenu Item" tooltip:"Tooltip Name"(your script code goes here)

    Obviously you will need to substitute names of your choosing into it.Here is what my final script looks like:

    MacroScript Random_Rotate category:"Rhys Tools" buttonText:"Random Rotate"tooltip:"Random Rotate"(for obj in $ do -- Loop over currently selected objects(randXrot = random -3.0 3.0 -- create a random X rotation value and store as a variablerandYrot = random -3.0 3.0 -- create a random Y rotation value and store as a variablerandZrot = random -3.0 3.0 -- create a random Z rotation value and store as a variablerot_obj = eulerangles randXrot randYrot randZrot -- Build our rotation object and storerotate obj rot_obj -- Apply the rotation to the current obj

    ))

    Save it and evaluate it (CTRL+E)

    Maxscript will appear to do nothing and a number will be returned in the listener. This is good.

    Now open Customize>Customize User Interface and under the category dropdown, there shouldbe one labeled "Rhys Tools" (or whatever you decided to call yours) You can now make this abutton or as I usually do, create a "Rhys Tools" menu bar item and add it there.

    now whenever you click the item, it will randomise the rotations of whatever objects you haveselected within +/- 3 degrees.

  • 8/12/2019 Dubs Maxscript Tutorials

    20/42

    D U B S M A X S C R I P T T U T O R I A L S

    Conclusion

    You may have realised that there are two fatal flaws. The first is that the script will crash if youhave nothing selected as $ will be undefined. Secondly what if you want different values than the

    +/- 3 degrees hard coded into the script? We will deal with these things in the next tut.

  • 8/12/2019 Dubs Maxscript Tutorials

    21/42

    D U B S M A X S C R I P T T U T O R I A L S

    Part 5 More basics

    This tutorial should take around 10 minutes to complete

    Intro

    In this tut we will be covering 4 things. Arrays, Error Checking,Messagebox prompts, and user interfaces.This is the longest tut yet and will take about 1/2 hour to complete.We left our random rotate script last time with two fatal flaws. 1, It

    crashes if there is no object selected and 2, there is also no way tospecify the range of random rotation.

    Chapter

    1

  • 8/12/2019 Dubs Maxscript Tutorials

    22/42

    D U B S M A X S C R I P T T U T O R I A L S

    Arrays

    First of all, I'd like to introduce a new concept - Arrays. If you're new to programming in generalthis will be a relatively meaningless term.Put most simply, an array is just a list of "things". Almost anything that can be saved as a variablecan be saved into an array. Lets make a quick array to get an idea about how they work.First of all, we need to create an empty array with a name. Fire up the listener and input and executethe following:

    ourFirstArray = #()

    ourFirstArray is our arbitrary name we have chosen, # is the symbol for arrays in maxscript, and the() encloses the contents of our array which is nothing in this case. Thus we have just created an

    empty array.Now we want to put something in our array. Maxscript has a useful little function called "append"which does just that. Usage is as follows:

    append ourFirstArray 1now type:

    append ourFirstArray 3

    now, type:

    ourFirstArray

    Maxscript will show us the contents of our array: #(1,3)

    We can keep adding to the array as much as we like. But how do we retrieve a certain value from it?Each item in the list is numbered from 1 upwards. So to retrieve the second item in our array weneed to ask for item 2 from ourFirstArray we do this by typing:

    ourFirstArray[2]

    Maxscript will return the integer 3 that we saved into the array earlier.

    One last thing that you will find very useful with arrays is the property .count - if we type thefollowing:

    ourFirstArray.count

    Maxscript will return 2 being the number of items in the array.

  • 8/12/2019 Dubs Maxscript Tutorials

    23/42

    D U B S M A X S C R I P T T U T O R I A L S

    Error Checking

    Open up the script we finished with last tut. it should look like this:

    MacroScript Random_Rotate category:"Rhys Tools" buttonText:"Random Rotate"tooltip:"Random Rotate"(for obj in $ do -- Loop over currently selected objects(randXrot = random -3.0 3.0 -- create a random X rotation value and store as a variablerandYrot = random -3.0 3.0 -- create a random Y rotation value and store as a variablerandZrot = random -3.0 3.0 -- create a random Z rotation value and store as a variablerot_obj = eulerangles randXrot randYrot randZrot -- Build our rotation object and storerotate obj rot_obj -- Apply the rotation to the current obj)

    )

    Now we have been referring to the current selection by typing $.Another way we can refer to the current selection is by typing the word "selection" This is actuallyan array of objects. Create a bunch of random objects in a scene. A bunch of teapots will do fine.Select them all. Now type:

    selection.count

    Maxscript will return the number of teapots that are selected! Try typing:

    selection[1]

    Maxscript will return the first teapot in the selection list. Now deselect the teapots so that nothing isselected and type:

    selection.count

    Maxscript returns 0. This is obviously useful to us. Lets now add an if clause to our script so that itwill only run the script if more than 0 items are currently selected. Add the following code:

    MacroScript Random_Rotate category:"Rhys Tools" buttonText:"Random Rotate"tooltip:"Random Rotate"

    (for obj in $ do -- Loop over currently selected objects(if (selection.count > 0) then -- if the current selection has more than 0 items, then do...(randXrot = random -3.0 3.0 -- create a random X rotation value and store as a variablerandYrot = random -3.0 3.0 -- create a random Y rotation value and store as a variable

  • 8/12/2019 Dubs Maxscript Tutorials

    24/42

    D U B S M A X S C R I P T T U T O R I A L S

    randZrot = random -3.0 3.0 -- create a random Z rotation value and store as a variablerot_obj = eulerangles randXrot randYrot randZrot -- Build our rotation object and storerotate obj rot_obj -- Apply the rotation to the current obj)

    ))

    Before we run it, lets add a warning to the user so that if they have no items selected, they willrealise why nothing is happening when they run the script.

    Message boxes

    We will use an else after our if/ then statement. Also we'll invoke the messagebox function todisplay an error message to the user. Add the following lines:

    MacroScript Random_Rotate category:"Rhys Tools" buttonText:"Random Rotate"tooltip:"Random Rotate"(for obj in $ do -- Loop over currently selected objects(if (selection.count > 0) then -- if the current selection has more than 0 items, then do...(randXrot = random -3.0 3.0 -- create a random X rotation value and store as a variablerandYrot = random -3.0 3.0 -- create a random Y rotation value and store as a variablerandZrot = random -3.0 3.0 -- create a random Z rotation value and store as a variable

    rot_obj = eulerangles randXrot randYrot randZrot -- Build our rotation object and storerotate obj rot_obj -- Apply the rotation to the current obj)else(messagebox "You must have at least one object selected!")))

    Now run the script. As it has the same macroscript name as last time, it should overwrite the

    previous version of the script and you can immediately use the menu item or button you made tokick off the new script. Make sure nothing is selected in the viewport and run it. Hopefully an errorprompt should appear telling you that you need to have at least one item selected!Good work. We have solved the first flaw with the script.

  • 8/12/2019 Dubs Maxscript Tutorials

    25/42

    D U B S M A X S C R I P T T U T O R I A L S

    User Interfaces

    Obviously to solve the second problem, we're going to have to give the user some way to enter in therange of values that he/she wants the random rotations to fall between.

    Open the Visual Maxscript Editor - Maxscript>visual Maxscript editor...It's very simple to use the editor to create an interface. Add elements from down the bottom andposition them in the workspace to your liking. Here is the results of my interface:

    Now, save your interface as a .ms file (make sure you don't save it as a .vms file which is thedefault.)Open the file in max as a maxscript and lets take a look. This is what mine looks like.

    rollout RandomRotateRollout "Random Rotate" width:162 height:122(groupBox grp1"Random Rotation Range" pos:[10,12] width:142 height:99button btn1"Randomly Rotate!" pos:[19,81] width:125 height:22spinner spn1"Minimum value " pos:[22,34] width:122 height:16 range:[-360.0,360.0,0.0]spinner spn2 "Maximum value" pos:[23,56] width:122 height:16 range:[-360.0,360.0,0.0])

    It contains 4 elements. A groupbox to keep things tidy, A button to run the script and two spinnersto select the random constraints.

  • 8/12/2019 Dubs Maxscript Tutorials

    26/42

    D U B S M A X S C R I P T T U T O R I A L S

    So how do we get the interface to run our script when we push the button?

    Inside the rollout function, we can add the following code:

    rollout RandomRotateRollout "Random Rotate" width:162 height:122(groupBox grp1"Random Rotation Range" pos:[10,12] width:142 height:99button btn1"Randomly Rotate!" pos:[19,81] width:125 height:22spinner spn1"Minimum value " pos:[22,34] width:122 height:16 range:[-360.0,360.0,0.0]spinner spn2 "Maximum value" pos:[23,56] width:122 height:16 range:[-360.0,360.0,0.0]

    on btn1pressed do -- when btn1is pressed do...(for obj in $ do -- Loop over currently selected objects(

    if (selection.count > 0) then -- if the current selection has more than 0 items, then do...(randXrot = random -3.0 3.0 -- create a random X rotation value and store as a variablerandYrot = random -3.0 3.0 -- create a random Y rotation value and store as a variablerandZrot = random -3.0 3.0 -- create a random Z rotation value and store as a variablerot_obj = eulerangles randXrot randYrot randZrot -- Build our rotation object and storerotate obj rot_obj -- Apply the rotation to the current obj)else(messagebox "You must have at least one object selected!")

    )))

    You'll see that I have just taken the contents of our macroscript and pasted it inside the "on btn1pressed do" brackets.That takes care of the button press! Now we just have to set things up so that the values of the twospinners are used as the random values instead of the hard coded +/- 3.We can do this by switching the hard coded values with: spn1.value and spn2.valuemake the changes.

    Now we have two more little things we need to do. We need to tell max to display the rollout whenour script starts running. we do this by adding the following after the rollout code:

    createDialog RandomRotateRollout 162 166

    And we also need to wrap the whole thing with our macroscript function. Our final script shouldlook like this:

  • 8/12/2019 Dubs Maxscript Tutorials

    27/42

    D U B S M A X S C R I P T T U T O R I A L S

    MacroScript Random_Rotate category:"Rhys Tools" buttonText:"Random Rotate"tooltip:"Random Rotate"(

    rollout RandomRotateRollout "Random Rotate" width:162 height:122(groupBox grp1"Random Rotation Range" pos:[10,12] width:142 height:99button btn1"Randomly Rotate!" pos:[19,81] width:125 height:22spinner spn1"Minimum value " pos:[22,34] width:122 height:16 range:[-360.0,360.0,0.0]spinner spn2 "Maximum value" pos:[23,56] width:122 height:16 range:[-360.0,360.0,0.0]

    on btn1pressed do -- when btn1is pressed do...(for obj in $ do -- Loop over currently selected objects(

    if (selection.count > 0) then -- if the current selection has more than 0 items, then do...(randXrot = random spn1.value spn2.value -- create a random X rotation value and store as avariablerandYrot = random spn1.value spn2.value -- create a random Y rotation value and store as avariablerandZrot = random spn1.value spn2.value -- create a random Z rotation value and store as avariablerot_obj = eulerangles randXrot randYrot randZrot -- Build our rotation object and storerotate obj rot_obj -- Apply the rotation to the current obj)else

    (messagebox "You must have at least one object selected!"))))createDialog RandomRotateRollout 162 166)

    Run the script. If you have no errors, it should just return a number in the listener. Now test it outon a bunch of objects!

  • 8/12/2019 Dubs Maxscript Tutorials

    28/42

    D U B S M A X S C R I P T T U T O R I A L S

    Conclusion and Homework

    Hopefully by now, you should be able to create basic interfaces to interact with your scripts.As an exercise, try adding separate range controls for X rotation, Y rotation and Z Rotation. Postyour solution in this thread if you can!

  • 8/12/2019 Dubs Maxscript Tutorials

    29/42

    Max script fun: a couple of examples

    A selection of example scripts provided by N ick Clark

    Intro

    In this section youll find a selection of example scripts for you toanalyze and deconstruct. Each scripts purpose is explained to giveyou a better understanding of how it works.

    Chapter

    2

  • 8/12/2019 Dubs Maxscript Tutorials

    30/42

    Introduction:Maxscript provides two main things for a max user. The ability to create new features in max, anda way to perform repetitive, or difficult tasks. Even if some of this makes no sense to you, I hopesome of it teaches you something new

    Take the example of a light which flickers. This would be tedious to animate by hand, but aparametric light flickering tool can be made quickly in maxscript, which can be used over and overagain.

    Here's a couple of examples of using of maxscript to reduce repetitive or difficult tasks. The moreyou see of maxscript, the more you can imagine what you can do with it. This is less of a tutorialthan the Dub's excellent work, but I hope the experience of this will help you write maxscripts inthe future.

    This picture illustrates the use of maxscript to alter the color of a group of objects. As you can see,the colors blend nicely. Coloring the objects this way manually would be possible, but would betime consuming.

  • 8/12/2019 Dubs Maxscript Tutorials

    31/42

    Here is the complete script:

    color_01= color 0 0 80color_02 = color 255 255 255

    stepsize_r = (color_02.r - color_01.r)/ $.countstepsize_g = (color_02.g - color_01.g)/ $.countstepsize_b = (color_02.b - color_01.b)/ $.count

    for i = 1to $.count do(newColor = (color ((i*stepsize_r)+ color_01.r-stepsize_r) ((i*stepsize_g)+color_01.g-

    stepsize_g) ((i*stepsize_b)+color_01.b-stepsize_b))$[i].wirecolor = newColor)

    To use it, select a row of objects, and run the script. If there are no errors, your objects will begiven a new wire color. There is supposed to be 2 lines of code between the brackets above, butthe forum is making it wrap. I hope this doesn't confuse people.

    Explanation:

    color_01= color 0 0 80

    color_02 = color 255 255 255

    color_01 and color_02 are the start and end colors to use for the color fade

    This is how you would define pure white in maxscript

    color 255 255 255Pretty obvious, right?

    stepsize_r = (color_02.r - color_01.r)/ $.countstepsize_g = (color_02.g - color_01.g)/ $.count

    stepsize_b = (color_02.b - color_01.b)/ $.count

    This bit divides the difference between the start and end color divided by the number of objects.One for red, green and blue. This gives us the amount of change of color in each step for use laterin the script. Don't worry if this makes no sense, it's the technique rather than the math I wantyou to experience.

  • 8/12/2019 Dubs Maxscript Tutorials

    32/42

    A "for" loop repeats a number of times, and gives an incrementing value for each cycle in theloop

    For i = 1to 10 do (print i)would print all the numbers from one to ten in the listener. UsingPrint is a great way of having feedback from your calculations, like a debugger would be used by aprogrammer (if you are doing this tutorial, you are a programmer!)

    In the code

    for i = 1to $.count do(blah blah blah)

    Any code in the brackets (blah blah blah) will be executed a number of times. In this case, thenumber ($.count) equals the number of selected objects. "i" will be incremented every time theloop repeats, until it reaches the ($.count) last number.

    $in max means "the selected object"$.countgives a number of how many selected objects you have.

    When working on a selection of objects, FOR and $ are really useful.

    The next lines of code do the actual work of coloring the objects. First, I calculate the new colorof the object.

    newColor = (color ((i*stepsize_r)+ color_01.r-stepsize_r) ((i*stepsize_g)+color_01.g-stepsize_g) ((i*stepsize_b)+color_01.b-stepsize_b))

    This defines a new color I have called newColor. The code here calculates the new color based oni (the step in the loop) and the step sizes calculated above. Don't worry if this bit is gibberish toyou right now, all experience is good.

    $[i].wirecolor = newColor

    This line applies the "newColor" to the objects.

    $[1] would be the first object in the selection$[2] would be the second object in the selection$[3] would be the third object in the selection

    When we use$[i], we can use i to define which object in the selection we are referring to. This iswhere theiin the "FOR loop" comes in.

    You might want to use something other than the wire color. You can create a material and applythe color to the diffuse channel with script instead. To find out what code to use. Manually makea material in the material editor, and watch the code that appears in the listener window. Use thiscode to create your material

  • 8/12/2019 Dubs Maxscript Tutorials

    33/42

    This method can be used to do almost anything to a group of selected objects. You couldrandomly scale objects, rotate them, adjust the material, apply modifiers. The possibilities arealmost endless.

    Here's a slightly more advanced example of something I could not do without maxscript:

    The full script can be found at the end of this tutorial in appendix 1

    This is one I made years ago, so please ignore the horrible, awful formatting, and lengthycalculations in the code. Select your grid of objects (has to be an even square), select the fourcolors by clicking on them and using the color picker, then click on the button.

    I don't expect you to understand this script, but there may be something of use to you in it. Partof the problem with maxscript is not knowing what it can do, and the more exposure to variousscripts, the better. Steal ideas (even code) from other scripts, use the listener and the help to workout what you need to do. Select a word in the Maxscript editor, and press F1. The help will gostraight to the relevent article (mostly).

    Happy scripting

  • 8/12/2019 Dubs Maxscript Tutorials

    34/42

    Appendix 1

    Nick Clarks color teapot grid script

    Just copy and past the below into the max script listener to run the script

    rollout DialogExample "ColorGrid" width:200 height:200

    (

    colorPicker cp1"" pos:[4,4] width:50 height:50 color:[255,0,0]

    colorPicker cp2 "" pos:[55,4] width:50 height:50 color:[0,255,0]

    colorPicker cp3 "" pos:[4,59] width:50 height:50 color:[0,0,255]

    colorPicker cp4 "" pos:[55,59] width:50 height:50 color:[255,128,0]

    button btn1"Colorize" pos:[8,113] width:97 height:18

    function theunction =

    (

    fn multiDimArr r c =

    (

    local arr, arrTMP

    arr=

    for i=1to r collect

    Appendix

    1

  • 8/12/2019 Dubs Maxscript Tutorials

    35/42

    (

    arrTMP=#()

    for j=1to c do

    (

    append arrTMP (0)

    )

    arrTMP

    )

    arr

    )

    root

    numCol = sqrt ($.count)

    numrow = sqrt ($.count)

    print (numCol as string + " x " + numRow as string)

    topLeftColor = #(cp1.color.red,cp1.color.green,cp1.color.blue)

    TopRightColor = #(cp2.color.red,cp2.color.green,cp2.color.blue)

    BottomLeftColor = #(cp3.color.red,cp3.color.green,cp3.color.blue)

    BottomRightColor = #(cp4.color.red,cp4.color.green,cp4.color.blue)

    -- Red

    myRedArray=multiDimArr numRow numCol

    myGreenArray=multiDimArr numRow numCol

  • 8/12/2019 Dubs Maxscript Tutorials

    36/42

    myBlueArray=multiDimArr numRow numCol

    myRedArray[1][1] = topLeftColor[1]

    myRedArray[1][numCol] = TopRightColor[1]

    myRedArray[numRow][1] = BottomLeftColor[1]

    myRedArray[numRow][numCol] = BottomRightColor[1]

    myNewRedArray = #(1,2,3)

    j = 1

    for i = 1to numRow do

    (

    myRedArray[i][j] = (((myRedArray[numRow][1]) - (myRedArray[1][1])) * (i-1)/ (NumRow-1)) + (myRedArray[1][1])

    )

    j = numCol

    for i = 1to numRow do

    (

    myRedArray[i][j] = (((myRedArray[numRow][numCol]) - (myRedArray[1][NumCol])) *(i-1)/ (NumRow-1)) + (myRedArray[1][NumCol])

    )

  • 8/12/2019 Dubs Maxscript Tutorials

    37/42

    for i = 1to NumCol do

    (

    for j = 1to NumRow do

    (

    myRedArray[i][j] = (((myRedArray[i][NumRow]) - (myRedArray[i][1])) * (j-1)/ (numCol-1)) + (myRedArray[i][1])

    )

    )

    for x = 1to numCol do

    (

    for y = 1to numRow do

    (

    myNewRedArray[(y+(numCol*(x-1)))] = myRedArray[x][y]

    )

    )

    -- Green

    myGreenArray[1][1] = topLeftColor[2]

    myGreenArray[1][numCol] = TopRightColor[2]

    myGreenArray[numRow][1] = BottomLeftColor[2]

    myGreenArray[numRow][numCol] = BottomRightColor[2]

    myNewGreenArray = #(1,2,3)

  • 8/12/2019 Dubs Maxscript Tutorials

    38/42

    j = 1

    for i = 1to numRow do

    (

    myGreenArray[i][j] = (((myGreenArray[numRow][1]) - (myGreenArray[1][1])) * (i-1)/ (NumRow-1)) + (myGreenArray[1][1])

    )

    j = numCol

    for i = 1to numRow do

    (

    myGreenArray[i][j] = (((myGreenArray[numRow][numCol]) -(myGreenArray[1][NumCol])) * (i-1)/ (NumRow-1)) + (myGreenArray[1][NumCol])

    )

    for i = 1to NumCol do

    (

    for j = 1to NumRow do

    (

    myGreenArray[i][j] = (((myGreenArray[i][NumRow]) - (myGreenArray[i][1])) *(j-1)/ (numCol-1)) + (myGreenArray[i][1])

    )

    )

  • 8/12/2019 Dubs Maxscript Tutorials

    39/42

    for x = 1to numCol do

    (

    for y = 1to numRow do

    (

    myNewGreenArray[(y+(numCol*(x-1)))] = myGreenArray[x][y]

    )

    )

    -- Blue

    myBlueArray[1][1] = topLeftColor[3]

    myBlueArray[1][numCol] = TopRightColor[3]

    myBlueArray[numRow][1] = BottomLeftColor[3]

    myBlueArray[numRow][numCol] = BottomRightColor[3]

    myNewBlueArray = #(1,2,3)

    j = 1

    for i = 1to numRow do

    (

    myBlueArray[i][j] = (((myBlueArray[numRow][1]) - (myBlueArray[1][1])) * (i-1)/ (NumRow-1)) + (myBlueArray[1][1])

  • 8/12/2019 Dubs Maxscript Tutorials

    40/42

    )

    j = numCol

    for i = 1to numRow do

    (

    myBlueArray[i][j] = (((myBlueArray[numRow][numCol]) - (myBlueArray[1][NumCol]))* (i-1)/ (NumRow-1)) + (myBlueArray[1][NumCol])

    )

    for i = 1to NumCol do

    (

    for j = 1to NumRow do

    (

    myBlueArray[i][j] = (((myBlueArray[i][NumRow]) - (myBlueArray[i][1])) * (j-1)/ (numCol-1)) + (myBlueArray[i][1])

    )

    )

    for x = 1to numCol do

    (

    for y = 1to numRow do

    (

    myNewBlueArray[(y+(numCol*(x-1)))] = myBlueArray[x][y]

  • 8/12/2019 Dubs Maxscript Tutorials

    41/42

    )

    )

    --

    mySelection = $ as array

    for x = 1to numCol do

    (

    for y = 1to numRow do

    (

    myRedColor = (myNewRedArray[y+((x-1)*numRow)])

    myGreenColor = (myNewGreenArray[y+((x-1)*numRow)])

    myBlueColor = (myNewBlueArray[y+((x-1)*numRow)])

    mySelection[y+((x-1)*numRow)].wirecolor = (color myRedColor myGreenColormyBlueColor)

    )

    )

    )

    on btn1pressed do theunction()

    )

  • 8/12/2019 Dubs Maxscript Tutorials

    42/42

    -- create the rollout window and add the rollout

    if DialogExampleFloater != undefined do

    (

    closerolloutfloater DialogExampleFloater

    )

    CreateDialog DialogExample width:114 height:140