[Closed] More noob questions:
Hi,
This is going to be the start of my daily threads asking important questions to my maxscript domination goal.
first, i followed along with a youutbe tutorial, but some of the things weren’t explained very well. if i don’t comprehend something i can’t ever use it. So
on btn_pos_X pressed do
(
for o in $ do
(rand_pos o spn_pos_X.value 0 0)
)
on btn_pos_Y pressed do
(
for o in $ do
(rand_pos o 0 spn_pos_Y.value 0)
)
on btn_pos_Z pressed do
(
for o in $ do
(rand_pos o 0 0 spn_pos_Z.value)
)
the maxscript documenation is a little confusing to me, but I couldn’t find out about why the zero’s are in different places in the for loop’s block for X,Y and Z.
seems a little strange, but it really doesn’t work any other way.
I also want to ask about for loops themselves, I’m having a hard time trying to wrap my head around them. In c++ a for loop would look like this:
for ( variable initialization; condition; variable update ) {
Code to execute while the condition is true
}
in maxscript, its typically
for (variable) in (object or selection) do
in c++ , the way i understood it was that variables usually get defined in the () first. in max, i’ve never seen that. I’m also wondering how “in” works.
So i’d really like to know how to read the for loop, so that i know what it does. if that makes any sense.
I see you have basic in C++ , then maxscript is much faster to learn.
btw in maxscript you can use attribute “selection”, selection mean object in selection (array of object in selection) n $ is single object in selection, mean singular [correct me if am wrong]. for your case you want to move object in selection , rather than using “for o in $ ” you can use “for o in selection” , but if you want to move single object [not grouped object] you can use “$.pos”. and random value in maxscript only use two value, i dont know if you making custom function , but standard random in maxscript its like this . random minValue maxValue
ex: in your case
on btn_pos_X pressed do
(
for o in $ do
(rand_pos o spn_pos_X.value 0 0)
)
become
on btn_pos_X pressed do
(
for o in selection do
(o.pos.x = random (spn_pos_X.value spn_pos_X_max.value) ) -- additional spinner needed or value for max value.
)
I hope it clear your problem.
wrong… actually it’s not absolutely correct.
first of all ‘selection’ or ‘$selecion’ is not an array of objects. it’s an objectset. instead of an array it’s “alive” thing and changes all the time if any object in scene changes its selection.
you can see the difference …
this is a sample:
delete objects
(
for k=1 to 10 do box()
select objects
nodes = for s in selection collect
(
deselect s
s
)
format "1:
object:%
used in loop:%
" objects.count nodes.count
select objects
nodes = for s in selection as array collect
(
deselect s
s
)
format "2:
object:%
used in loop:%
" objects.count nodes.count
)
next is about using single $…
it calls ‘pathName’ value. some sort of ‘wildcard’ for list of objects.
the $ means currently selected. if is’t a single selection the $ returns a node, if it’s a multiple selection the $ returns set.
you can see it in the example below:
delete objects
(
for k=1 to 10 do box()
select objects[1]
print $.name
select objects
print (try $.name catch(getCurrentException()))
ok
)
rand_pos is a custom function right?
So rand_pos o spn_pos_X.value 0 0 means that you pass to that function the object that will be moved – o, and then the X(spn_pos_X.value), Y(0) and Z(0) position of that object.
The first argument, passed to the function is the object that will be moved, the second argument is the X position of the object, the third argument is the Y position, the fourth argument is the Z position.
When you press the btn_pos_X the script will randomize only the X position of the passed objects. That is why you have o spn_pos_X.value 0 0, the second argument is the spinner value, which will affect the X position of the objects. The two 0 are the values for the Y and Z position and since they have to stay unchanged you pass to the function 0.
When you press the btn_pos_Y the script will randomize only the Y position of the passed objects. That is why you have o 0 spn_pos_Y.value 0, the second argument is the X position, which have to stay unchanged and its value is 0 , the second argumen it she Y position which have to be changed, so you pass the spn_pos_Y value. The third argument is the Z position, which have to stay unchagned so you pass 0 to the function.
So, when you have to change the position on sertain axis you pass the spinner value, when axis have to stay unchanged you pass 0.
For loops:
This is how you can define for loop.
for i = 1 to 100 do print i
If you have an array of objects you can use:
objsArr = #($Box01, $Box02, $Box03)
-- get the elements directly
for b in objsArr do print b.name
or
objsArr = #($Box01, $Box02, $Box03)
--
for b = 1 to objsArr.count do print objsArr[b].name
Open MaxScript reference and search for this:
For Loop By Index Vs For Loop Through Collection Performance
for ( variable initialization; condition; variable update ) {
Code to execute while the condition is true
}
If you Really need that kind of form in maxscript, it’s a pretty straightforward while loop:
i = 1 --if you're used to C/C++ remember that most "stuff" (i.e. arrays) in maxscript start with 1, not 0.
while i < 100 do
(
print i
print someArrayThatYouHave[i]
i += 1 --same as i = i+1, or ++i in C (and C++?), i don't think maxscript has a post-increment like i++
)
But in maxscript there is a way to include additional conditionals in a for loop, or alter the step like this:
for i = 1 to 100 while i != 50 do print i --will stop at 50
for i = 1 to 100 where (mod i 2 == 0) do print i --not quite the same as a C for loop conditional, but convenient
for i = 1 to 100 by 7 do print i --increments i by 7 each time
for i = 10 to 1 by -1 do print i --this should be worth remembering, as for i = 100 to 1 doesn't work on its own
You can use break, exit, continue in a loop, just like in C/C++, BUT YOU SHOULDN’T. It’s incredibly slow.
“in” works on collections. “for obj in objects do” will cycle through objects, putting each object in the obj variable for the code inside the loop. You can have an array of anything and cycle through the elements same way too: “for i in intArr do print i”, “for str in ArrayOfStrings do print str”, etc…
Even something like this:
for i = 1 to 100 while i != 50 where (mod i 2 == 0) do print i
Even…
for i = 100 to 1 by -5 while i != 50 where (mod i 2 == 0) do print i
also i can answer the question that people frequently ask on max forums…
what is the difference between ‘selection’ and ‘$selection’, ‘objects’ and ‘$objects’, etc… ?
‘selection’, ‘objects’ are the object sets
‘$selection’, ‘$objects’ are the pathname values, which can be continued as any path:
$selection/box*
$objects/geometry/b*00?
...
Ok thanks maiuu,
haha i should have probably seen that about the zero’s. It totally didn’t make sense to me at all.
and yes rand_pos was a function.
thanks for the example for loops, it makes alot more sense now, i just haven’t read very much maxscript. I actually stopped reading my c++ book b/c i was understanding things alot better in maxscript, it’s alot easier to absorb things that are very difficult in C++.
@ denisT
when you say object sets, are you talking about certain types of objects? or all objects in the scene?
and about the pathway values, what do you mean exactly?
thanks for all the help its been a good thread
I’ve been playing around with a script that creates boxes in random places, i have a few questions about it
resetMaxFile #noprompt
mybox = box length: 5 width: 5 height: 5 wirecolor: green
for i in 1 to 5 do
(
box_copy = copy mybox
box_copy.pos.x = (i*random 0 25)
box_copy.pos.y = (i*random 0 25)
box_copy.pos.z = (i*random 0 25)
select objects
addmodifier box_copy (turbosmooth iterations: 2)
)
I’m sure you know, but the first box that is created does not have a random position or the turbosmooth modifier applied to it.
how do you also include the first created to get random position and modifier?
also, on
box_copy.pos.x = (i*random 0 25)
I use the variable(i) and times (*) it by random,
it definitely works, but i was wondering how it works. and why i couldn’t use the (+, -, /, ^,) signs? and what using (*) actually does in this case using random?
Well, you can create your first box at random position like this:
mybox = box length:5 width:5 height:5 pos:[(random 0 25), (random 0 25), (random 0 25)] wirecolor: green
I may be wrong, but i don’t think you can specify modifiers to the object creation function. To add a modifier to your first box, you do what you did with the boxes in the loop, just after you created the box and before the loop:
addmodifier mybox (turbosmooth iterations: 2)
Now since you are copying “mybox” in the loop, you should remove the addmodifier there. No need for it as the box you are copying already has it and it will be copied.
What it does is very straightforward. It first calls the “random 0 25” function, then multiplies the result by i, which is 1 for the first loop/box, 2 for the second, 3 for the third, and so on… A less confusing way to write it would be i*(random 0 25).
I’m a little surprised about the + – / ^ part, since it seems to work just fine in this case.
If you were expecting something else here… Since you mentioned you were learning C++, you probably heard what a pointer is. In maxscript * is also a deferencing operator, same as in C, and in terms of syntax it works much the same way as in C, with the exception that in maxscript you can’t move to the next pointer in a linked list using “somePointer+1”, maxscript isn’t that fancy-pants. That is: “i*someValue” is multiplication, “somePointer” – dereferencing somePointer, “i( *somePointer )” – multiplication after dereferencing.
Also, if you’re just starting out, it’s worth reading through maxscript basics in the maxscript help – it is written in a very newbie-friendly manner, intended to be understandable for folks that don’t necessarily come from a programming background.
hi Zhalktis,
thanks for the reply,
for some reason i thought the
mybox = box length:5 width:5 height:5 pos:[(random 0 25), (random 0 25), (random 0 25)] wirecolor: green
wasn’t creating anything, but defining the variable. But your way makes it alot easier.
one of the examples I say was (i*random 0, 50), i wasn’t sure if that was a mathematical sign, or if it was a multiplicatioin sign, i didn’t know how it was multiplying it. so you made it very easy to understand, thanks.
i’ve been reading through the documentation, and it is very helpful. thanks for the time