[Closed] Using strings as variable names?
This might be something really simple, but Ive been searching through the maxscript reference for an answer to no avail. For a piece of code I am writing, I need to be able to use a string that is put together earlier in the function as a variable name to store a mesh.
To be exact, they are going to be different fish types – so depending on the type of fish structure passed into the function, it grabs the name from the structure definition, lets say a shark:
nameOf = substring (classOf type as string) 9 5 –where ‘type’ is the struct called ‘shark’ that has been passed into the function
It then does some string addition to give me the name ‘sharkMesh’ (or whaleMesh, troutMesh, whatever). Problem is, I cant for the life of me figure out how to get Maxscript to let me use this as a variable name to then store actually store mesh in so that I can recall the various meshes later.
And if this seems like a roundabout way of working -it is. Im certain there are faster, more streamlined approaches to it, but this is part of a uni project where I am trying to show how, with certain workarounds, you can implement object oriented style programming techniques in maxscript. Not necessarily for any benefit, but the lecturer really loves his OO stuff so thats what Im trying to show.
something like that:
struct SharkStruct (name = "Shark", color, numTeeth)
struct CarpStruct (name = "Carp", color, numBones)
fn makeFish type =
(
fish = type()
case fish.name of
(
"Shark":
(
fish.color = white
fish.numTeeth = random 500 1500
)
"Carp":
(
fish.color = yellow
fish.numBones = 100
)
)
fish
)
makeFish SharkStruct
makeFish CarpStruct
It is possible to call Execute() on a string to convert it to its MAXScript value. If it happens to be a variable, you get the variable’s value.
The problem is that Execute() generally operates in the global scope. So if you say
bobo = 10
-->10
execute ("bo"+"bo")
-->10
but if you move the variable into local scope,
(
local someVar = 42
execute "somevar"
)
--> undefined
because execute “somevar” looks for somevar in the global scope, but the actual variable is in the local scope.
But if the scope is named (e.g. a rollout for example) and the variables you are accessing are local to that scope but the named scope itself is accessible through a global variable, you can use that to access its locals!
For example,
rollout test "Test"
(
local test1 = 10
local test2 = 25
local test3 = 42
button btn_something "Don't Press Me"
)
createDialog test
execute "test.test1"
execute "test.test2"
execute "test.test3"
execute "test.btn_something.caption"
the result will be
Rollout:Test
true
10
25
42
"Don't Press Me"
As you can see, calling execute on a string that prefixes the local variable with a global one gets you in there…
Now you can assign a TriMesh to any of these by calling the code inside the execute:
execute "test.test1=(createInstance box).mesh"
This will replace the value of 10 with a TriMesh of a box inside the rollout.
So if you ask again
execute "test.test1"
-->TriMesh
Perhaps “getNodeByName” is what you are looking for?
sharkname = "shark"
teapot name:sharkname
troutname = "trout"
sphere name:troutname
fish = getNodeByName sharkname
format "fish is a %
" (classof fish)
fish = getNodeByName troutname
format "fish is a %
" (classof fish)
Cheers for the answers, they have actually helped me solve a few other problems Ive been having (especially that execute command), but not quite this one. Perhaps I over complicated things in my first post with strings and meshes; while that is a description of what I want to do, the problem could be as simple as this:
I have a string that contains “abc”, and I want to get Maxscript to take that and use it as the name of a variable. I just need some way declaring a NEW variable, named from a string, and assigning whatever I want to – lets say 123.
While this may work:
abc = 123
execute “abc”
(will give you 123)
These wont
execute “abc” = 123
execute(“abc”)=123
as, according to the listener, there is “– No “”=”” function for (Global:execute “.
Hmm… this may be trickier than I thought.
Could you be specific of a case when this is needed. Whenever I think I need to do this I usually find out I’m wrong
But
theVal = 42 --new variable with the value you want in abc
-->42
execute("abc" + "=" + theVal as string) --assing as part of the execute
-->42
abc --check abc, it is 42 now
-->42
--this the the same as
execute ("abc=42")
--or any other string execution you might want to do.
--In fact, people use execute() for creating whole dynamic UIs with buttons, variables
--and functions, so this is the least you can do
check globalVars Structure in MXS help
thename = “abc”
execute (“global ” + thename)
globalVars.isglobal thename
globalVars.set thename 123
globalVars.set “abc” 123
Thank you guys so much, guess I just misunderstood how exactly to use the execute command, but that last post has helped me to acheive exactly what I was after! Cheers fellas.
Just to make it even clearer, execute() is just like MAXScript>Run Script, but instead of evaluating a file from disk, it evaluates the code you supply via a string. So ANYTHING that MAXScript can do can be evaluated using execute, including building a 1000 lines user interface inside a string or stringStream and then running the MAXScript evaluation over it
Here is a simple example:
txt = "rollout myRollout \"Test\" (
"
for i = 1 to 10 do
(
txt += "button btn_"+i as string + " \"Button " + i as string + "\" align:#center width:120
"
txt += "on btn_"+i as string + " pressed do format \"You Pressed Button %
\" "+i as string + "
"
)
txt += ")"
execute txt
createDialog myRollout