[Closed] Macroscript strangeness on opening
I have some load save functions on my macroscript that are using the syntax: MyRollout.MyCheckbox = true etc. The thing is that when I was working on the script, so changing it, evaluating the macro then running it from a toolbar it worked fine. But when it loads up with max, then I run it from the toolbar there is no access to MyRollout.MyCheckbox as Myrollout is undefined.
Why would this be happening?
Jordan Walsh
do you define that rollout outside of the macroscript scope? If so, that’s probably why. When you evaluate your script file, 3ds Max takes the macroscript code (everything from ‘macroscript … (’ to the matching closing ‘)’ and uses that and -only- that for the code to evaluate when the macroscript is used in a toolbar button, menu entry, etc.
You’ll have to either include all of your code within the macroscript scope, or place your script file in a startup folder, so that it always gets re-defined completely.
The above is just a guess, though
Richard’s probably bang on the money with that one, but can you show us the code, or at least the skeleton to see how you’re implementing it?
Everything is defined inside the macroscript scope.
Here is a cutdown version:
macroScript CheckNSave Category: "01_Animation" toolTip:"Zero One File Checker And Saver" Icon:#("CheckNSave",1)
(
---==================FUNCTIONS==================---
fn LoadPresets =
(
if ZeroOneFileCheckPresetsArr != undefined do
(
for i =2 to ZeroOneFileCheckPresetsArr.count do (try ((execute ("RO_CheckNSave."+ZeroOneFileCheckPresetsArr[i]))) catch(print ("Error: "+ZeroOneFileCheckPresetsArr[i]+ " not loaded")))
)
)
---==================ROLLOUTS==================---
rollout RO_CheckNSave "Zero One File Saver v1.03"
(
Button B_SavePresets "S"
Button B_LoadPresets
on RO_CheckNSave open do
(
if ZeroOneFileCheckPresetsArr == undefined do
(
B_LoadPresets.enabled=false
)
LoadPresets() --Attempt to load saved presets
)
on B_SavePresets pressed do
(
persistent global ZeroOneFileCheckPresetsArr=#()
for i in RO_CheckNSave.controls do
(
case classof i of
(
CheckBoxControl:append ZeroOneFileCheckPresetsArr (i.name+".checked = "+(i.checked as string))
ComboBoxControl:append ZeroOneFileCheckPresetsArr (i.name+".selection = "+(i.selection as string))
spinnerControl:append ZeroOneFileCheckPresetsArr (i.name+".value = "+(i.value as string))
)
)
B_LoadPresets.enabled=true
B_DelPresets.enabled=true
Messagebox "Preset settings saved to file" title:"Zero One File Checker and Saver"
)
on B_LoadPresets pressed do
(
LoadPresets()
Messagebox "Preset settings loaded from file" title:"Zero One File Checker and Saver"
)
)
createdialog RO_CheckNSave 600 875 style: #(#style_resizing, #style_toolwindow, #style_sysmenu)
)
First of all, EXECUTE() operates ONLY in global scope. Unless the variable RO_CheckNSave is declared as global, execute() will not “see” it.
So in the beginning of the macro, just after the MacroScript line and before the Function, add
global RO_CheckNSave
to ensure that the rollout is visible in the global scope.
Even if you were not using the execute() method but a function attempting to access the rollout that is defined AFTER the function, it would have failed to “see” the rollout because the variable RO_CheckNSave would have been undefined at the moment of the function creation. In such cases, you can leave the RO_CheckNSave local to the MacroScript body, but pre-declared BEFORE the function that uses it. In that case, you would have said
local RO_CheckNSave
But in general the variables of the dialog rollouts are typically declared as global in order to be able to close the rollout before opening it again. So your code should be
macroScript CheckNSave Category: "01_Animation" toolTip:"Zero One File Checker And Saver" Icon:#("CheckNSave",1)
(
global RO_CheckNSave
try(destroyDialog RO_CheckNSave)catch()
---==================FUNCTIONS==================---
fn LoadPresets =
(
if ZeroOneFileCheckPresetsArr != undefined do
(
for i =2 to ZeroOneFileCheckPresetsArr.count do (try ((execute ("RO_CheckNSave."+ZeroOneFileCheckPresetsArr[i]))) catch(print ("Error: "+ZeroOneFileCheckPresetsArr[i]+ " not loaded")))
)
)
---==================ROLLOUTS==================---
rollout RO_CheckNSave "Zero One File Saver v1.03"
...
Of course, there is probably no good reason to have the function outside of the rollout – you could define it inside the body of the rollout and you would not need to resolve the rollout using execute at all…
Bobo, I did try making the rollout global and now I have just tried putting the function inside the rollout, but it still didnt work!!! grrr!
So i tried just having filein in the macro and loding it as an ms. All good now!
Still, I dont really understand why it didnt work after your changes Bobo.
Jordan,
To tell you the truth, I did not test your code, I just made the changes from top of my head by looking at it. So there could be other problems, potentially hidden by the try()catch().
If I find a minute, I might play with the whole script and actually evaluate it in Max
Btw, great job on that Space Chimps game cut-scene sand!
Ok, got some time to test it out and it works!
The example you posted had the line
B_DelPresets.enabled=true
but B_delPresets was not included in your test, so I remarked it.
Then I added a spinner definition to the code, changed the LoadPresets function to loop from 1 to number of controls instead of 2 (as the spinner was the first element of the array) and I was able to both save and load the presets as you would expect.
Cheers Bobo! It was a fun project. Ill upload another krakatoa/fume heavy shot for you to check out today
Did you save it as a macro, reload max then run it from the toolbar? because this is the only reason it failed. Simply executing the script when I was editing it worked fine, but as soon as it waonly executed from the toolbar it didnt work. Fileing-in the script solves it for now for me, so I guess problem solved