Scripted custom attributes are properly saved to and loaded from scene files.
You can assign a fixed, global definition ID to an attributes definition.
This acts in a similar way to class IDs in scripted plug-ins. Such definitions are global across any number of scenes that custom attributes may be present in and all instances of custom attributes of a global definition will have the same shape. The ID is specified with a new header parameter, ' attribID:
’
attributes <name> attribID: #(<number>, <number>) ( ... )
The ID number pair is chosen to be unique, perhaps generated with the genClassID() function in MAXScript. Attribute definitions without attribID's are private to the current MAX session.
genClassID [ returnValue:<boolean>]
This method generates a random class ID similar to #(0x9b7ea231, 0xb6db86ef), and prints it to Listener. You can just cut and paste this class ID into your script to use the generated ID. If the optional returnValue keyword is supplied and set to true, the value will be returned as the result of the method call.
Definitions are identified depending on whether they are global or private definitions.
Global definitions have explicit attribID: parameters, which define a globally unique ID for that definition and ensure that any object with custom attributes based on a definition with that ID will be follow the same definition. Whenever you evaluate an attributes definition with a particular attribID: you will update all objects that have custom attributes based on that definition, and loading objects with attributes of that attribID will update themselves to the current definition.
Private definitions have no explicit attribID: parameter (they effectively have an internally-generated random one). Each time you evaluate one, except as described in the redefinition section below, a completely distinct definition is created with its own internal ID.
In the case of both global and private definitions, the 'attributes' definition construct returns the definition as its value, so you would typically assign that value to a local and then use it to add custom attributes to objects via the custAttributes.add ()
function.
EXAMPLE
local def def = attributes "Game Data" ( parameters ... rollout ... ) custAttributes.add $box01 def custAttributes.add $box02 def
This example adds a separate set of the defined custom attributes to box01 and box02. The definition is shared between the two boxes.
This is a private definition, it has no attribID:, so if you evaluated the 'def = attributes (...)' again, it would \*not\*
automatically update box01's and box02's attributes, as used to happen in prior builds, but create a new definition.
In order to redefine a specific attribute definition so that all objects that had attributes added using it will be updated, you can use one of two schemes that operate on the actual definition value (as it sits in the 'def' variable in the above, for example).
First, you can use the 'redefine:' attributes definition parameter:
EXAMPLE
attributes "Game Data" redefine:def ( parameters ... rollout ... )
This expects an existing attributes definition as the value given in the redefine: parameter and will update it to the definition that follows, and update any custom attributes made from that particular definition value. In the example, this would update $box01 and $box02.
Alternatively, you can use the custAttributes.redefine
method:
custAttributes.redefine <def> <definition_string>
EXAMPLE
local new_def = "attributes \"Game Data\" ( ... )" custAttributes.redefine def new_def
This is particularly useful in situations where you are generating the attributes definition automatically as a string. You can use this function to compile and apply the redefinition to a particular definition object in one go, without having to construct a name for the object, as you would if you used the redefine: parameter scheme.
To redefine the attributes on some object, say based on the defData in that object's custom attributes, you might use this sequence:
old_def = custAttributes.getDef $box03 1 -- get existing def
old_def_data = custAttributes.getDefData old_def -- get my defData from it
new_def_string = generate_new_def old_def_data ... -- make new def string
custAttributes.redefine old_def new_def_string -- redefine it
These redefinition techniques can be used with global definitions (with explicit attribID:), but are strictly unnecessary since the particular definition value is specified uniquely by the attribID: parameter. In any situation that you evaluate a global definition, all custom attributes in the current scene made from that definition will be updated.
Next Topic: