Frequently Asked Questions > Writing Better and Faster Scripts > How To Make It Better? >

# How To Make It Better?

MAXScript FAQ > How To Make It Better?

## Avoid using persistent global variables

A good idea gone bad.

Initially added to support scripted controllers and xrefs.

Problems:

- No control over whether they are loaded

- Overwriting previous values

Solutions:

- Use the new scripted controllers in 3ds Max 8

- Use scripted CAs for persistent data storage- see below.

## Using scripted CAs for persistent data storage

Scripted Custom Attributes can be used instead of persistent global variables to store data with the scene file, avoiding the problems mentioned above.

A scripted CA can be placed on the scene root:
    sceneDataCADef =attributes sceneDataCADef version:1 attribID:#(0x61e9ff5f, 0x63784819)
    (
    parameters main rollout:params
    ( note type:#string ui:et_note default:"")
    rollout params "Scene Data Parameters"
    ( edittext et_note "Note: ")
    )

    thescene = (refs.dependents rootnode)[1]
    rootNodeDataCA = undefined
    if (custattributes.add rootnode sceneDataCADef) do
     rootNodeDataCA = rootnode.custAttributes[rootnode.custAttributes.count]
    sceneDataCA = undefined
    if (custattributes.add thescene sceneDataCADef) do
     sceneDataCA = thescene.custAttributes[thescene.custAttributes.count]
    rootNodeDataCA.note
    sceneDataCA.note
    rootNodeDataCA.note = "rootnode"
    sceneDataCA.note = "thescene"

If the file is saved and reloaded, you can access the CAs:
    rootNodeDataCA = undefined
    if(rootnode.custAttributes.count != 0) do
     rootNodeDataCA = rootnode.custAttributes[rootnode.custAttributes.count]
    sceneDataCA = undefined
    if(thescene.custAttributes.count != 0) do
     sceneDataCA = thescene.custAttributes[thescene.custAttributes.count]

If the file is brought in as an XRef scene, you can still access the CAs:
    xr = xrefs.getXRefFile 1
    xr_root = xr.tree
    xr_rootNodeDataCA = undefined
    if (xr_root.custAttributes.count != 0) do
     xr_rootNodeDataCA = xr_root.custAttributes[xr_root.custAttributes.count]

## Building UI on Script/Expression Controller

By placing a scripted Custom Attributes definition on a script or expression controller, you can provide a custom UI for the controller.

- Define the CA to contain animatable parameters and rollout for UI.

- Create a script controller.

- Apply the CA to the script controller.

- Apply the script controller.

- Create variables in the script controller.

- Assign Target values to the variables, specifying the CA parameters as the targets.

- Display the CA’s UI using createDialog or newRolloutFloater & addrollout

EXAMPLE
    floatDataCADef = attributes floatDataCADef version:1
    (
    parameters main rollout:params
    ( prop1 type:#float ui:s_prop1 )
    rollout params "Parameters"
    ( spinner s_prop1 "Prop1: ")
    fn getRollout = params
    )

    sc = float_Script()
    custattributes.add sc floatDataCADef
    floatCA = sc.custattributes[1]
    sc.addTarget "prop1" floatCA[#prop1]

    displayControlDialog sc ""

    mscas =for ca in sc.custattributes where isMSCustAttrib ca collect ca
    rollouts =for ca in mscas where isproperty ca #getrollout collect ca.getrollout()
    if rollouts.count == 1 then
     createdialog rollouts[1]
    else if rollouts.count > 1 do
    (
     width = rollouts[1].width
     for ro in rollouts do
      width = amax width ro.width
     rof = newrolloutfloater "" (width+13) 0 0 0
     for ro in rollouts do addrollout ro rof
     height = 6
     for ro in rollouts do
      height += ro.height + 24
     rof.size = [rof.size.x,height]
    )

#### See Also

- How To Make It Faster?

- Frequently Asked Questions