[Closed] Looping and appending names?
Hi,
I’m trying to adjust this script that someone here helped me right awhile ago. Basically it creates a dummy and aligns it to an object at everyframe of animation. It looks like this.
theAnimSource = $Object01
theObjToAlign = $Dummy01
for t = animationrange.start to animationrange.end by 1 do
with animate on at time t theObjToAlign.transform = theAnimSource.transform
I now have to apply this to say 100+ dummys and 100+ objects. Is there a way to loop through and see if there is an object named object02, then 03, etc. and make a dummy that matches it, until it runs out of objects. Right now my solution is copying and pasting the script until have the same script over and over with object01’s and dummy01’s name changed to 1 number further, like 02,03,04 etc. here’s a small example.
theAnimSource = $Object01
theObjToAlign = $Dummy01
for t = animationrange.start to animationrange.end by 1 do
with animate on at time t theObjToAlign.transform = theAnimSource.transform
theAnimSource = $Object02
theObjToAlign = $Dummy02
for t = animationrange.start to animationrange.end by 1 do
with animate on at time t theObjToAlign.transform = theAnimSource.transform
theAnimSource = $Object03
theObjToAlign = $Dummy03
for t = animationrange.start to animationrange.end by 1 do
with animate on at time t theObjToAlign.transform = theAnimSource.transform
theAnimSource = $Object04
theObjToAlign = $Dummy04
for t = animationrange.start to animationrange.end by 1 do
with animate on at time t theObjToAlign.transform = theAnimSource.transform
theAnimSource = $Object05
theObjToAlign = $Dummy05
for t = animationrange.start to animationrange.end by 1 do
with animate on at time t theObjToAlign.transform = theAnimSource.transform
theAnimSource = $Object06
theObjToAlign = $Dummy06
for t = animationrange.start to animationrange.end by 1 do
with animate on at time t theObjToAlign.transform = theAnimSource.transform
theAnimSource = $Object07
theObjToAlign = $Dummy07
for t = animationrange.start to animationrange.end by 1 do
with animate on at time t theObjToAlign.transform = theAnimSource.transform
theAnimSource = $Object08
theObjToAlign = $Dummy08
for t = animationrange.start to animationrange.end by 1 do
with animate on at time t theObjToAlign.transform = theAnimSource.transform
theAnimSource = $Object09
theObjToAlign = $Dummy09
for t = animationrange.start to animationrange.end by 1 do
with animate on at time t theObjToAlign.transform = theAnimSource.transform
theAnimSource = $Object10
theObjToAlign = $Dummy10
for t = animationrange.start to animationrange.end by 1 do
with animate on at time t theObjToAlign.transform = theAnimSource.transform
I’m sure there is a way more optimized method for this, can any one help ?
Thanks so much for any help.
You could make two arrays. One with the dummies and one with the objects you want the dummies aligned to.
In the loop you can set a variable like “a” for the first item in array one and “b” for the first item in array two. In the loop you can have it match the position of “a” to “b” then add 1 to “a” and 1 to “b” before looping again.
The first loop is set for one hundred iterations so you may need to adjust that number depending on how many objects are in your scene. For instance, if you have and obect in your scene named $Object437 then you’ll want to change the loop to be “for i = 1 to 437 do”
(
struct dumToObj (obj, dummyObj)
local strArray = #()
for i = 1 to 100 do
(
if i <= 9 then i = ("0" + i as string) else i = i as string
if isValidNode (getNodebyName ("Object" + i)) then
(
d = dummy name:("Dummy" + i)
t = dumToObj obj:(getNodebyName ("Object" + i)) dummyObj:d
append strArray t
t.dummyObj.transform = t.obj.transform
)
)
with animate on
(
for t = animationrange.start to animationrange.end do
(
for i in strArray do
(
at time t i.dummyObj.transform = i.obj.transform
)
)
)
)
Hope it helps –Jon
Thanks for the help guys.
I attempted it based on gonemad’s info, but i’m too noobish in maxscript and couldn’t get it to work.
Jon your script works perfectly, thanks a lot.
I hope to get good enough to script things like this with ease.
Cheers,
David
I have a similar problem with getting objects in a loop. I generate a rollout dynamically with rolloutCreator, which has a for-loop to create edittexts based off of a numerical value elsewhere.
In an on pressed state for one of the buttons in the UI, my script uses a for-loop to go through each of the edittexts generated by the rolloutcreator and put them as a value in a multi-dimensional array:
for k = 1 to (num_bases as integer) do
(pBaseCh = getNodeByName ("baseCh" + (k as string))
pBaseMd = getNodeByName ("baseMd" + (k as string))
if(x[j] == pBaseCh.text) then (baseAry[i][j] = pBaseMd.text)
)
but then I get this error:
>> MAXScript Rollout Handler Exception: -- Unkown property: "text" in undefined <<
I have tried this, too (I know execute() operates on a global scope… but that’s what I want it to do!)
for x = k to (num_bases.text as integer) do
(execute
([indent]"if(x[j] == " + ("baseCh" + (k as string)) + ".text) then
([indent]baseAry[i][j] = " + ("baseMd" + (k as string)) + ".text
)"
[/indent])
[/indent])
but then I get this error:
>> MAXScript Rollout Handler Exception: -- No ""get"" function for undefined <<
Any thoughts?
Thanks,
-Mogul
You’ve got two problems here:
pBaseCh = getNodeByName (“baseCh” + (k as string))
pBaseMd = getNodeByName (“baseMd” + (k as string))
What if there is no matching node (object)? Then pBaseCh or pBaseMd, or both, are undefined. That’s one part of the error message.
if(x[j] == pBaseCh.text) then (baseAry[i][j] = pBaseMd.text)
.text is not a property of a node. That’s the other part.
- Michele
Ah yes, I see. Nodes are objects in the world, and I was trying to use getNodeByName for dynamically created edittexts. Hmm… how would I obtain a handle on an edittext created dynamically, then? You see, I have an arbitrary number of edittexts that are generated with a for-loop and a rolloutCreator, then I need to go through each edittext and do something with its value.
Thank you for your response, it has shed some light,
-Mogul
Well, it depends where you want to get the text from. Just make sure that whatever you’re putting in the edittext .text property is actually a string.
You might start off by putting some constant text into each edittext field, just to make sure this part of the loop is working:
for i…
for j…
baseAry[i][j] = “Some text or other”
When you’ve ascertained that the text is indeed appearing in the edittext text boxes, then you can look at putting in some kind of string values that you get on the fly.
Presumably you know the variable names of the edittext boxes you are trying to fill. Is this what you’ve put into an array?
I don’t know where you’re trying to get the text to put in the edittext boxes, so I can’t really give you any pointers on what code to use to do this.
- Michele