Notifications
Clear all

[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.

9 Replies
1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

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.

2 Replies
(@thatoneguy)
Joined: 11 months ago

Posts: 0

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

(@bobo)
Joined: 11 months ago

Posts: 0

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.

1 Reply
(@bobo)
Joined: 11 months ago

Posts: 0

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