Intro
In this tut we'll be covering 4 things. Rotations, Comments, Saving and running scripts and making macroscripts.
Hopefully you still have your max file with the randomised fence posts from tut 3. Open it up.
Maxscript Editor
From now on, we won't be running our main scripts from the listener. The listener is still useful for testing snippets of code before you incorporate it into your main script. Also you'll need to look 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 random snippets of code that you've written for one-off tasks and the other for finished release quality scripts with proper error checking, documentation and interfaces etc.
Last time we finished with a script to randomly set the positions of the fenceposts. Now we want to modify 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 will store 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 with the 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
the following:
rotate $ cubeRotationObject
The cube should rotate 20 degrees around the Y axis.
Back to our script. Hopefully you should be ahead of me now with a clear idea how to modify the script to randomly rotate the posts. In case you're lost, here is the code:
(this time, type it into our blank new maxscript file)
for obj in $ do
(
randXrot = random -3.0 3.0
randYrot = random -3.0 3.0
randZrot = random -3.0 3.0
rot_obj = eulerangles randXrot randYrot randZrot
rotate obj rot_obj
)
Select all the fence posts (or if you don't have the file from tut3, create an array of fence posts and select them all) and run the maxscript by hitting CTRL+E (evaluate) All the posts should now have random heights, positions and rotations giving a much more organic look than what we started with.
Comments
Once your scripts grow beyond a few lines long, comments start to get really important so that you don't forget what parts of your code do what. Also if you need to give your code to anyone else, good comments will make things much easier for them. A comment is text notes inside your script that the Maxscript parser knows to ignore. You can make a comment by typing "--" Anything after the -- will be interpreted as a comment and is not executed.
If you need to write more than one line, you'll need to put -- at the beginning of each line. Now go through and comment your random rotation script. You'll notice that the comments show as green.
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 variable
randYrot = random -3.0 3.0 -- create a random Y rotation value and store as a variable
randZrot = 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 store
rotate obj rot_obj -- Apply the rotation to the current obj
)
Macroscripts
I'm now going to show you how to make your script into a macroscript that you can bind to a shortcutkey 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 or Menu 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 variable
randYrot = random -3.0 3.0 -- create a random Y rotation value and store as a variable
randZrot = 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 store
rotate 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 should be one labeled "Rhys Tools" (or whatever you decided to call yours) You can now make this a button 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
have selected within +/- 3 degrees.
-
game design team
We have emerged as the leading online community for game development of all levels. Our expertise encases all facets for writing PC , Mobile and Online of 2D and 3D Gaming programming and applications development, for instance by using the latest 3D engines, scripting languages and animation techniques, our experienced and qualified team deals with all kind of requirements, whether it be a beginner's choice or an expert gaming action. Most importantly, we endeavor to offer compelling solution and eminent support to our growing community of prospective players and customers.
We're going to step it up a level in this tutorialThis one should take about 10 mins to complete.
Intro
We will be covering four main areas.
1: Variables and data types
2: Loops
3: Comparison Operators
4: If statements
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 something in a locker (variable) - it might be a number, a piece of text or even a modifier - and give it a name it will 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 now we 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.5 now 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.643
Integer - These numbers are whole numbers only ie 5 or 200
Boolean - true or false
String - 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.
Loops
Loops are where maxscript becomes really powerful and useful. They enable maxscript to do
repetitive tasks rather than you and the mouse.
Imagine you have built a scene with many objects. You have added a turbosmooth modifier to
all the objects with an iteration value of 2. This is now causing you problems because the
scene is too slow to navigate and you wish you had set the iterations to 1 with a
rendertime setting of 2.
Here is the code:
for obj in $ do
(
obj.modifiers[#turbosmooth].iterations = 1
obj.modifiers[#turbosmooth].useRenderIterations = true
obj.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 current
selection, do the commands inside the following brackets."
( - We open the brackets
obj.modifiers[#turbosmooth].iterations = 1 - we set the iterations to 1
obj.modifiers[#turbosmooth].useRenderIterations = true
obj.modifiers[#turbosmooth].renderIterations = 2 - these lines should be obvious to you by
now.
) - 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
them all.
You can test the code by making a bunch of objects all with turbosmooth on them. THEY MUST
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 with an error. This
obviously isn't very satisfactory.
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 the
numbers 5 and 2, we can compare them in different ways try typing the following into the
listener:
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 = true
obj.modifiers[#turbosmooth].renderIterations = 2
)
That will check an object to make sure it has a turbosmooth modifier and then if it does,
run through the code in the following brackets
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 = 1
obj.modifiers[#turbosmooth].useRenderIterations = true
obj.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.
I'll hopefully do a few of these over the next while. I'll start off really really basic for those who have always wanted to learn maxscript but haven't been able to get started. (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 your everyday work. You can then extend your knowledge as you come across tasks that you can *almost do with your current knowledge.
Intro
Ok, first of all I'll go over a few basics.
To follow allong with these tuts, open the maxscript listener by
hitting F11.
The pink area up the top is the listener where if you enable the
macrorecorder, it will tell you what max is doing in maxscript
terms as you do regular tasks in max. We won't pay attention to
this area in this tut.
The white area is where everything will be happening. Delete the
"Welcome to maxscript" message so we have a blank slate to start
with.
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 to the selection or you can refer
to it by name. The way maxscript refers to objects is by their
name with a $ in front. So to refer to the sphere you just
created, type:
$Sphere01
Now, with the cursor at the end of that, hit the enter on the
numeric keypad. That will execute the current 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 with different radii and you want to just
change their segment count? (a common problem)
Working on selections of many objects
I referred earlier to the fact we can refer to objects by
referring to the current selection. In maxscript 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 $Sphere01
Now 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 and execute 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 : boolean
false
virtualinfocom