The various optional clauses inside the plug-in body are similar to those for scripted utilities and tools.
There is an additional scripted plug-in specific clause <parameters>
for defining scene-savable and Track View visible parameters for the plug-in.
The <plugin_body>
of a scripted plug-in definition is made up of a sequence of plug-in clauses as follows:
<plugin_body> ::= { <plugin_clause> }+
Plug-in clauses define the components of a scripted plug-in and can be one of these five basic things:
Local variables, functions, or structure definitions - They are variables, functions, and structures whose scope is the plug-in. These locals will exist as long as the instance of the plug-in exists. The visibility of locals and accessing scripted plug-in locals from external code are described in Visibility of Locals, Functions, Structures, and User-Interface Items in Rollout Code and Accessing Locals and Other Items in a Rollout from External Code.
Parameter blocks - They define a set of parameters for the plug-in, which are like plug-in local variables, but are directly animatable and are saved to and restored from scene files. You can also associate each parameter with appropriate user-interface elements in one of the plug-ins rollouts. When associated in this way, the parameters are "wired" to their spinners, checkboxes, and others. Both update automatically as the other changes, so you do not have to write any user-interface event handlers for them. These parameters correspond to the visible parameters you see in other 3ds Max plug-ins.
Mouse tools - They are used to perform a set of actions based on mouse clicks in the 3ds Max viewports and are described in Scripted Mouse Tools.
Rollouts - They can be displayed for the scripted plug-in. For scripted plug-ins that extend an existing plug-in, these rollouts can be displayed in addition to or replace the existing plug-in’s rollouts. Rollout definitions are described in Utility Clauses.
Event handlers - They are special kinds of functions associated with particular events. Event handlers specify the processing that must occur when a user creates an instance of the scripted plug-in or when 3ds Max calls the scripted plug-in. These actions generate named events and the optional event handler you supply for that event is called when the action occurs.
Formally, the syntax of a <plugin_clause>
is defined as follows:
<plugin_clause> ::= <local_variable_decl> |
<local_function_decl> |
<local_struct_decl> |
<parameters> |
<tools> |
<rollouts> |
<event_handler>
The <local_variable_decl>
, <local_function_decl>
, and <local_struct_decl>
are exactly the same as local variable, function, and structure definitions in MAXScript:
<local_variable_decl> ::= local <decl> { , <decl> }
<decl> ::= <name> [ = <expr> ] -- optional initial value
<local_function_decl> ::= [ mapped ](function | fn) <name> { <argument> } = <expr>
<local_struct_decl> ::= struct <name> ( <member> { , <member> } )
<member> ::= ( <name> [ = <expr> ] | <local_function_decl> )
Global variables cannot be declared as a plug-in clause. However, they can be declared within event handler scripts. If you need to ensure a variable name references a global variable, declare the variable name as global immediately before defining the plug-in in your script.
When writing scripts, it is good programming practice to explicitly declare your local and global variables. Implicit declaration is provided as a short-hand, typically used when working in the Listener interactively or developing short scripts. When developing extended scripts, explicitly declaring variables can reduce errors and improve readability of the code. It is also recommended that you declare as local all variables unless you really want them to be global variables. The reasons for this are described in Scope of Variables.
Plug-in locals are attached to plug-in objects and each new instance of the scripted plug-in has its own local storage area. When you reference a plug-in local in a plug-in function or handler, it accesses the local storage of the currently active object. For example, the object currently open in the command panel. Plug-in local storage is not permanent across scene saves and loads (unlike <parameters>
). You can provide initial values for locals, as elsewhere in MAXScript, and the locals are re-initialized when a saved scripted plug-in object is loaded again as part of a scene file open. You can also do this by hand in a create
event handler if you supply one in the plug-in.
Plug-in locals are accessible to script code outside a plug-in as a normal property on the object, but note that they might be hidden by parameters or other common object properties if they have the same name. When accessing a property on a scripted plug-in object, MAXScript first looks in the common properties (such as, .pos
, .scale
, .parent
, and others on a node), then in the parameters, and then in the locals for a property name match.
version
Yields the current version of the object as an Integer value.
this
Yields the instance of the scripted plug-in.
delegate
Yields the instance of the plug-in you are extending in an extends:
plug-in.
loading
In 3ds Max 6 and higher, yields True while the plug-in instance is in the process of being loaded.
The version
local variable contains the version number specified in the scripted plug-in definition. See Updating Scripted Plug-ins for more information on this variable.
The this
local variable always contains the MAXScript value corresponding to the current instance of the scripted plug-in. This variable provides a guaranteed way of accessing parameters on the new object within plug-in code (in case there are locals or globals with the same name), and it is a way of referencing the plug-in in case you want to store it to a variable.
The delegate
local variable contains the MAXScript value corresponding to the instance of the plug-in being extended. To access common properties or subAnim properties in the instance of the plug-in being extended, you need to do so using the delegate
local variable.
FOR EXAMPLE
delegate.width = thisWidth
inside a plug-in function or handler will set the .width
property in the instance of the plug-in being extended. The delegate local variable in a scripted plug-in that creates a scene object does not contain the node itself, but the BaseObject of that node. As such, you can not access the node level properties of the object being created. An exception to this is the node’s transform, which is exposed to the scripted plug-in through a local variable called nodeTM
. This variable is described in the applicable scripted plug-in type topics.
If the extends:
parameter is not supplied for a plug-in, delegate
returns undefined
.
As well as local variables, you can define local functions and local structures, just as you can with scripted utilities and rollouts.
You can define one or more parameter blocks in a scripted plug-in.
A parameter block has the form:
parameters <name> [type:#class] [rollout:<name>] (
{ <param_defs> }+
{ <event_handler> }
)
A parameter block defines a set of parameters for the plug-in, which are like plug-in local variables, but are directly animatable and are saved to and restored from scene files. You can also associate each parameter with appropriate user-interface elements in one of the plug-ins rollouts. When associated in this way, the parameters are "wired" to their spinners, checkboxes, and others. Both update automatically as the other changes, so you do not have to write any user-interface event handlers for them. These parameters correspond to the visible parameters you see in other 3ds Max plug-ins. Parameters in the parameter block do not participate in 3ds Max’s undo system, therefore changes to the parameter values are not undoable.
The <name>
you give to a parameter block becomes permanently associated with the parameter block and is used by MAXScript to connect to the right parameter block in a plug-in object that is being loaded from a scene file. This becomes important as you modify a plug-in script and yet there are still objects corresponding to the old definition in other files. When the old-version object is loaded, MAXScript attempts to convert it to the new definition using the current parameter block definition as a guide. To properly do this, each parameter in a parameter block is also given a permanent name. So, if you have existing objects of your plug-in in other files, do not change the parameter block names randomly or they will not be loadable.
The optional type:<#class>
specifies that the parameters in the parameter block are "class" parameters. This means that there is one copy of each parameter for *all* the objects of this plug-in class; they all share the parameter. Examples of existing class parameters are the creation type and type-in parameters in a typical geometry primitive.
The optional rollout:<name>
specifies a rollout definition elsewhere in the plug-in body to use as the user-interface rollout for the parameter block's parameters. A limitation of the internal parameter block mechanism requires that each parameter block be associated with a separate rollout and each rollout be associated with only one parameter block. This means that each rollout you want to have in the plug-ins user interface must have its own separate parameter block.
The <param_defs>
are definitions for each parameter in the parameter block.
They have the form:
<name> type:<#name> [localizedName:<string>] [nonLocalizedName:<string>] [tabSize:<integer>]
[tabSizeVariable:<boolean>] [default:<operand>] [animatable:<boolean>]
[subAnim:<boolean>] [ui:<ui_def>] [assettype:<asset_type>]
[invisibleInTV:<boolean>] [showAllInTV:<boolean>]
[readOnly:<boolean>] [readOnlyAsset:<boolean>] [enumAsAsset:<boolean>]
[useNodeOsValidity:<boolean>] [useNodeTmValidity:<boolean>]
The <name>
is permanently associated with the parameter in the same sense as parameter block names. They are used to connect to the right parameter when loading objects of the scripted plug-in and allow you to make certain changes to a script and still be able to load old version objects. So, as with parameter block names, do not change or re-use parameter names if you have scene files with old version objects you want to get at.
The optional localizedName:<string>
specifies a localized string that is used when 3ds Max attempts to display the parameter's localized name. This localized name is shown in places such as TrackView when the parameter type is animatable, or holds a material or texturemap; in the Material Editor when displaying the UI for a subMaterial or subTexture; or in the Slate Material Editor when displaying slot names. This localized name is returned from the MAXScript getSubAnimName()
, getSubAnimNames()
, getSubMtlSlotName()
and getSubTexmapSlotName()
methods. When not specified, the parameter's name
property is displayed.
Available in 3ds Max 2021 and higher.
The optional nonLocalizedName:<string>
specifies a nonlocalized (ENU) string that is used when an attempt is made to access the parameter in a script. This option should be specified if the parameter's name property is not the same as the localizedName
option when 3ds Max is running in the en-US locale. The nonlocalized name is returned from the MAXScript getSubAnimName()
, getSubAnimNames()
, getSubMtlSlotName()
and getSubTexmapSlotName()
methods when they are called with the localizedName/localizedNames options set to false. When not specified, the parameter's name property is returned instead. Available in in 3ds Max 2022 and later
The type:<#name>
parameter is required and defines the parameter type. It can be one of the following:
#float |
animatable |
#integer |
animatable |
#index |
animatable |
#color |
animatable |
#rgb |
animatable, alias of #color |
#frgba |
animatable, available since 3ds Max 6 |
#point3 |
animatable |
#point4 |
animatable, available since 3ds Max 6 |
#boolean |
animatable |
#angle |
animatable |
#percent |
animatable |
#worldUnits |
animatable |
#matrix3 |
|
#string |
|
#filename |
|
#colorChannel |
animatable |
#time |
animatable |
#radiobtnIndex |
|
#material |
|
#texturemap |
|
#bitmap |
|
#node |
|
#maxObject |
|
#paramBlock2 |
available since 3ds Max 2018 |
#point2 |
available since 3ds Max 2018 |
or one of the following types which are arrays of the above base types:
#floatTab |
|
#intTab |
|
#indexTab |
|
#colorTab |
|
#rgbTab |
Alias of #colorTab |
#frgbaTab |
Available since 3ds Max 6 |
#point3Tab |
|
#point4Tab |
Available since 3ds Max 6 |
#boolTab |
|
#angleTab |
|
#percentTab |
|
#worldUnitsTab |
|
#matrix3Tab |
|
#stringTab |
|
#filenameTab |
|
#colorChannelTab |
|
#timeTab |
|
#radiobtnIndexTab |
|
#materialTab |
|
#texturemapTab |
|
#bitmapTab |
|
#nodeTab |
|
#maxObjectTab |
In 3ds Max 2010 and higher, when the parameter is of type #filename
, to handle the parameter as an asset you also need to specify assettype:<asset_type>
where argument is one of the following enums:
#Other |
#Bitmap |
#XRef |
#Photometric |
#Animation |
#VideoPost |
#BatchRender |
#ExternalLink |
#RenderOutput |
#PreRenderScript |
#Script |
#PostRenderScript |
#Sound |
#Container |
TYPE_INDEX, TYPE_INDEX_TAB, TYPE_MATRIX3, and TYPE_MATRIX3_TAB have been added as supported PB2 data types in MAXScript. TYPE_INDEX is used for parameters that are 0-based, but are exposed in MAXScript as 1-based, for example, a vertex index.
The above data types are also available in scripted parameter blocks with types of #index
, #indexTab
, #matrix3
, and #matrix3Tab
respectively.
FOR EXAMPLE
height1 type:#index animatable:true default:1 ui:height1
height3 type:#indexTab tabSizeVariable:true
m3a type:#matrix3 default:(matrix3 [1,0,0] [0,0,1] [0,-1,0] [53.1187,-6.50834e-007,14.8893])
m3b type:#matrix3tab tabSizeVariable:true
type:#index
is animatable, and #matrix3
is not.
type:#index
must behave in the same manner as type:#int
, except the data value stored is 0-based, but is seen by MAXScript as 1-based. So, if you had an object using an animated height1 property (as defined above),
YOU WILL SEE SOMETHING LIKE
$.height1
15
$.height1.controller.value
14.0
The type:#integer
parameters can be associated with dropDownList, ComboBox, and ListBox user interface controls using the UI: option in the parameter definition. The value in the parameter corresponds to the 1-based index of the currently selected item in the user interface control.
ListBox user interface controls were not supported for integer parameter association in releases prior to 3ds Max 7.
Typically, you would populate this list with names or strings, and the value in the associate parameter effectively becomes a code number for these names or strings. Setting the value of the parameter using a script will automatically cause the corresponding item in the dropDownList to be selected if the UI for that object is currently open.
#worldUnits
and #worldUnitsTab
specify that a parameter holds a world distance value that is kept internally as a system units float.
FOR EXAMPLE
parameters main rollout:params
(
height type:#worldUnits ui:heightSpin
)
Note that this does not cause any spinner display to be automatically shown in current display units. You also need to specify type:#worldUnits
on the associated rollout spinner definition.
#node
and #nodeTab
are used to store references to nodes. The nodes stored in these parameters cannot create a circular dependency. For example, if you were creating a scripted helper, and set the helper as a target or parent of a camera, you cannot store the camera node in a #node
or #nodeTab
parameter. Likewise, if you created a scripted modifier or material, and store a node in a #node
or #nodeTab
parameter, you cannot apply the modifier or material to that node.
#node
and #nodeTab
can take these flags, which affect whether the plugin is re-evaluated if the node is animated:
useNodeTmValidity
- set to true to cause the scripted plugin to take into account the node's transform validity.useNodeOsValidity
- set to true to cause the scripted plugin to take into account the node's object space / geometry pipeline validity.The various xxTab
parameter types allow you to store an array of values having the corresponding type. The initial size of the array is specified using the tabSize:
specifier. If tabSizeVariable:true
is specified, the size of the array will be automatically expanded when you assign to an higher array index.
FOR EXAMPLE
parameters main rollout:params
(
mapAmounts type:#floatTab tabSize:4 tabSizeVariable:true ui:(map1Amount, map2Amount, map3Amount, map4Amount)
)
defines an array parameter containing four float elements (defined by the tabSize:
parameter).
The number of UI items must match the tabSize. If the user increases the tab size using a script, new UI elements are not created for the new items. If the user decreases the number to less than the UI element count, this will lead to a crash.
You can associate a separate rollout element with each array parameter element. These parameters appear as arrays when accessed in the plug-in handler code.
FOR EXAMPLE
a = mapAmounts[i]
Because tabSizeVariable:true
was specified, the following will automatically increase the array size to 10:
mapAmounts[10] = a
You can also increase or decrease the array size by assigning a value to the .count
property.
Each element in an array parameter whose base type is a number of some kind ( floatTab
, intTab
, percentTab
, and so on) is independently and automatically animatable unless you specify animatable:false
. You can get at and assign individual controllers using the .controller
property.
FOR EXAMPLE
c = mapAmounts[i].controller
The optional parameter default:<operand>
specifies an initial default value for the parameter. The <operand>
expression has to be convertible by MAXScript to the base type of the parameter.
The optional parameter animatable:<boolean>
specifies whether the parameter is animatable and hence visible in the track view. Only those base types marked as animatable in the above type list can be specified as animatable. Defaults to true
.
The optional parameter subAnim:<boolean>
can be specified for the 3ds Max object types: #node
, #material
, #textureMap
, and #maxObject
. If specified as true
, the 3ds Max object is made visible as a sub-object track in track view. Defaults to false
.
The optional parameter ui:<ui_def>
is used to specify which user-interface element in the parameter block's associated rollout is to be linked to this parameter. When linked, the handling of user actions for these elements are automatic and they also update automatically to follow any changes to the parameter caused by animation, scripts, and others. For example, in the following, the parameter block named main
is associated with the rollout named params
. The parameters height
and spread
are then linked with the spinners named height
and spread
in that rollout:
EXAMPLE
parameters main rollout:params
(
key type:#node subAnim:true
fill type:#node subAnim:true
back type:#node subAnim:true
height type:#float animatable:true default:10 ui:height
spread type:#float animatable:true default:10 ui:spread
on height set val do
(
key.pos.z = val
back.pos.z = val * 1.5
fill.pos.z = val * 0.5
)
)
rollout params "Light Parameters"
(
spinner height "Height"
spinner spread "Spread"
)
After this is done, the parameter and spinner are linked and changes in one are reflected immediately and automatically in the other. Further, if the parameter is animated, the spinner will show red keyframe highlights when the time slider is positioned at a keyframe for that parameter as with other 3ds Max plug-ins. The kinds of user-interface items that can be linked to particular parameter types is limited to the following sensible combinations:
Parameter type | Rollout user-interface item |
---|---|
#integer |
spinner, slider, radioButtons, checkbox, checkbutton |
#float |
spinner, slider |
#time |
spinner, slider |
#color |
colorpicker |
#angle |
spinner, slider |
#percent |
spinner, slider |
#colorChannel |
spinner, slider |
#boolean |
checkbox, checkbutton |
#node |
pickButton |
#textureMap |
mapButton |
#material |
materialButton |
#worldUnits |
spinner, slider |
The optional parameter invisibleInTV:<boolean>
if set to true hides the parameter in TrackView. This only applies to parameters that are subAnim or animatable normally shown in TrackView. The default is false.
The optional parameter showAllInTV:<boolean>
if set to true, and the parameter is subAnim or animatable normally shown in TrackView, and the parameter is also a Tab type parameter, then all of the tab elements are shown in TrackView. The default is false.
The optional parameter readOnly:<boolean>
if set to true, means the parameter's value cannot be set using MAXScript, it can only be changed in the user interface. Similarly, the optional readOnlyAsset:<boolean>
parameter applies to asset type parameters, and when true, the parameter's value cannot be set using the Asset Tracker or MAXScript. It can only be changed using the user interface.
The optional parameter enumAsAsset:<boolean>
if set to true for asset type parameters, specifies that the asset held by the parameter is reported when performing scene asset enumeration.
EXAMPLE
t=teapot()
bitmap_holder = attributes "bitmap_holder"
(
parameters main
(
thebitmap type:#filename assetType:#bitmap enumAsAsset:true
)
)
custattributes.add t.baseobject bitmap_holder
t.baseobject.thebitmap = "fir1.tga"
function get_names name a = append a name
files = #()
enumerateFiles t.baseobject get_names files
enumerateFiles t.baseobject get_names files #missing
files
--> #("fir1.tga")
The following event handlers are associated with parameters. These handlers are called when a parameter is assigned a value, or when the parameter value is retrieved.
on <name> set <arg> do <expr>
on <name> preSet <arg1> do <expr>
on <name> postSet <arg1> do <expr>
A set
handler can be supplied for any of the parameters in the block and it will be called whenever the parameter is updated, either through an associated rollout user-interface item or directly, especially using the MAXScript property assignment. In general, the way you code change handlers is to supply set
handlers for parameters, rather than on <item>
change handlers for spinners, checkboxes, and others in the rollout definition. A set
handler in used in the previous example to update the light positions when the height parameter value changes.
The set
handlers are also called when an instance is created or loaded so that common dependent actions can be taken such as, setting up other dependent system object or delegate properties.
set
handler is not called on create or load.Available since 3ds Max 2018: The preSet and postSet handlers guarantee the state of the parameter value. In most situations you should use preSet instead of set, as the parameter value is guaranteed to be the original value, while the <arg>
passed through is the new value. To alter the <arg>
value passing through, do not change <arg>
, but rather return a new value from the handler. MAXScript will set the parameter to this returned value.
In situations where you do not need to alter the value passing through, or do not care about the original parameter value (for example, when you are updating a UI element), use postSet.
on <name> get <arg> do <expr>
A get
handler can be supplied for any of the parameters in the block and it will be called whenever the parameter value is retrieved. This will occur when the user interface updates itself or a script accesses the parameter. It will also occur when a viewport is redrawn or a render occurs if a script (including the scripted plugin itself) accesses the parameter as part of the redraw or render. In all these cases, the animated value is retrieved one or more times. The get
handler is called with a single argument which is the current value stored in the paramblock (or underlying controller if the parameter is animated). The currentTime
variable is set to the time at which the value is being retrieved and not necessarily the current slider time, since you can ask a parameter for its value for any specified time. If you implement the get
handler, you must return a value, and that value is returned as the value of the parameter to the value requester. If you do not want to modify the value, but just monitor accesses, return the argument. You can also compute and return any value of the appropriate type.
on <name> set <arg1> [<arg2>] do <expr>
on <name> get <arg1> [<arg2>] do <expr>
For both get and set handlers, if the parameter is of tab type, a second argument can be specified for the handlers. The tab index will be placed in the second argument.
EXAMPLE
plugin helper getsetHandlerTest
name:"DummyEx"
classID:#(1453456,5432110)
category:"Scripted Primitives"
extends:dummy
(
parameters main rollout:params
(
nodeTab type:#nodetab tabSizeVariable:true
on nodeTab set val index do format "set nodeTab: % : %\n" val index
on nodeTab get val index do (format "get nodeTab: % : %\n" val index;val)
intTab type:#inttab tabSizeVariable:true
on intTab set val index do format "set intTab: % : %\n" val index
on intTab get val index do (format "get intTab: % : %\n" val index;val)
point3Tab type:#point3tab tabSizeVariable:true
on point3Tab set val index do format "set point3Tab: % : %\n" val index
on point3Tab get val index do (format "get point3Tab: % : %\n" val index;val)
intVal type:#integer
on intVal set val do format "set intVal: %\n" val
on intVal get val do (format "get intVal: %\n" val;val)
)
rollout params "Parameters"
(
)
)
----------------------------------
--Test the Get and Set Handlers:--
----------------------------------
x=getsetHandlerTest() --create an instance of the above Helper
b=box()
s=sphere()
x.nodeTab[1] = b
x.nodeTab[2] = s
x.nodeTab[1]
x.nodeTab[2]
x.intTab[1] = 9
x.intTab[2] = 20
x.intTab[1]
x.intTab[2]
x.point3Tab[1] = [pi,pi,pi]
x.point3Tab[2] = [e,e,e]
x.point3Tab[1]
x.point3Tab[2]
x.intVal = 20
x.intVal
with animate on at time 100 x.intVal = 120
OUTPUT:
getsetHandlerTest
set intVal: 0
$DummyEx:DummyEx01 @ [0.000000,0.000000,0.000000]
$Box:Box01 @ [0.000000,0.000000,0.000000]
$Sphere:Sphere01 @ [0.000000,0.000000,0.000000]
set nodeTab: $Box:Box01 @ [0.000000,0.000000,0.000000] : 1
$Box:Box01 @ [0.000000,0.000000,0.000000]
set nodeTab: $Sphere:Sphere01 @ [0.000000,0.000000,0.000000] : 2
$Sphere:Sphere01 @ [0.000000,0.000000,0.000000]
get nodeTab: $Box:Box01 @ [0.000000,0.000000,0.000000] : 1
$Box:Box01 @ [0.000000,0.000000,0.000000]
get nodeTab: $Sphere:Sphere01 @ [0.000000,0.000000,0.000000] : 2
$Sphere:Sphere01 @ [0.000000,0.000000,0.000000]
set intTab: 9 : 1
9
set intTab: 20 : 2
20
get intTab: 9 : 1
9
get intTab: 20 : 2
20
set point3Tab: [3.14159,3.14159,3.14159] : 1
[3.14159,3.14159,3.14159]
set point3Tab: [2.71828,2.71828,2.71828] : 2
[2.71828,2.71828,2.71828]
get point3Tab: [3.14159,3.14159,3.14159] : 1
[3.14159,3.14159,3.14159]
get point3Tab: [2.71828,2.71828,2.71828] : 2
[2.71828,2.71828,2.71828]
set intVal: 20
20
get intVal: 20
20
set intVal: 120
120
OK
on <name> tabChanged <arg1> <arg2> <arg3> do <expr>
A tabChanged
handler can be supplied for any Tab parameters in the block and will be called when an operation is performed on the tab itself. The arguments are:
arg1
- The type of change. Will be one of: # insert
, # append
, # delete
, # refDeleted
, # setCount
, or # sort
. All are pretty evident except for # refDeleted
. This type will occur when a MAXWrapper stored in the tab is deleted.
arg2
- The tabIndex associated with the operation. If not applicable, it will have a value of 0.
arg3
- The count associated with the operation. If not applicable, it will have a value of -1.
For example, if you append an item to a tab that already contains one member, you will get a call to this handler with arguments of: #append 2 1. The set handler is not called, so you must handle this message in the same way as the set handler.
Plug-ins can define local mouse tools. Although, you can have any number of local tools and start them as needed, you typically supply a single tool with the reserved name create
. This is taken to be the create tool for objects created in the Create panel and is invoked automatically when you create scripted plug-in objects. Tool definitions are described in Scripted Mouse Tools.
Creatable scene scripted plug-ins (scripted plug-ins that are not invisible, temporary, or extend another plug-in) require a create
tool. A create
tool, if present on a non-temporary extending plug-in will override the delegate's create tool. The animate state is implicitly turned off while the create
tool is executed.
A local variable WS73099cc142f487553098682e12ac2fc2bc7-722e
is accessible within the create
tool. This variable contains a Matrix3 value. This value is in the active grid coordinate system. This variable allows the create
tool to set the transform of the node currently being created. Also, within the create
tool you must use the gridX
values rather than worldX
values in all cases because object-creation is managed in the active grid coordinate system.
Plug-ins can define local rollouts. These have the same syntax as local rollouts in scripted utilities. Unlike utility local rollouts, these rollouts are automatically opened as appropriate for the plug-in type (in the command panel, Material Editor, and others).
on <rollout> open
event handler to pick up these values. Rollout definitions are described in Utility Clauses.on <rollout> reload do ...
This event handler is defined for rollouts in scripted plug-ins. This handler is called in a scripted material, environment, or render effect whenever an instance of the plug-in is open in the Material Editor or render effects dialog, and another instance of the same plug-in class is selected. In this situation, the existing rollout is not closed and re-opened, but rather left open and 'loaded' with the new instance. The 'reload' handler is called after the new instance is installed in the rollout and can be used in place of on <rollout> open do ...
handler to update the rollout. The open handler is not called in this case. The reload event handler is not called if the scripted object has custom attributes associated with it, rather the existing rollout is closed and a new rollout opened.
on <rollout> setTime <val> do ...
This event handler is defined for rollups in scripted materials and texturemaps. This handler is called whenever the time slider is changed while the rollout is displayed. <val>
is the slider time.
As with mouse tools, scripted plug-ins respond to certain actions in 3ds Max by implementing handler functions. All types of scripted plug-ins support the following event handlers. You can use these event handlers to perform any extra initialization needed such as, loading up plug-in local variables or initializing properties of the plug-in’s delegate.
on create do <expr>
The create
event handler is called whenever an instance of a scripted plug-in is created in a scene file. The animate state is implicitly turned off while the create
event handler expression is executed.
on postCreate do <expr>
When a scripted plugin is created, its create handler is called, the set handler for all paramBlock items are called, and then the postCreate handler is called. Available in 3ds Max 6 and higher.
on load do <expr>
The load
event handler that is called whenever an instance of a scripted plug-in is loaded from a scene file. The animate state is implicitly turned off while the load
event handler expression is executed.
on postLoad do <expr>
When a scripted plugin is loaded, its update handler is called if necessary, the load handler is called, the set handler for all param block items are called, and then the postLoad handler is called. In most cases, you do not want to perform any action in the param block item set handlers when they are called during a load. You can make processing with the set handlers conditional using the 'loading' automatic variable.
Available in 3ds Max 6 and higher.
It is recommended that MAX objects not be deleted in the load or postload handlers, or in the param block item set handlers when they are called during a load. These calls occur much later in the scene load than the update handler, and deleting objects will most likely not cause a failure. However, this can not be guaranteed.
on update do <nodeVar>
The update
event handler that is called whenever an instance of a scripted plug-in is present in the scene file, and the definition of the scripted plug-in is changed (if you define a scripted plug-in, create an instance of the plug-in object in the scene, and then change and execute the script defining the scripted plug-in, the update event handler defined in the new definition of the scripted plug-in script is called for each instance of the plug-in object in the scene). See the Updating Scripted Plug-ins topic for more information.
You must not cause a MAX object to be deleted in an update handler. The file is not done loading when the update handler is called and deleting an object might cause a crash when 3ds Max tries to finish loading the now deleted object.
on attachedToNode <nodeVar> do ...
Called whenever a scripted plug-in scene object (geometry, camera, light, helper, shape) is bound to a node in the scene such as, during create mode. The node that the current plug-in instance is being attached to is given as the first argument. In the event of scene node instancing, this handler might be called several times, whenever the base object is instanced to a node. Note that, in most cases, this will be called in the middle of a create mode and consequently actions such as, creating other nodes in the handler body are forbidden as they are generally in 'on create' handlers.
on detachedFromNode <node> do ...
This is a handler to scene object scripted plug-ins. It is called whenever a node that references a plug-in instance is deleted in the scene. Note that in the presence of instancing, there might still be other nodes referencing the base object instance.
on deleted do...
Called whenever the scripted plug-in object is finally deleted. This might not occur immediately such as, when a scene node containing a scripted base object is deleted because the object is held onto by the undo stack in case the node delete is undone by the user. The delete might occur when the undo stack is cleared such as, a file new or reset.
on clone <original> do ...
Called whenever an instance of a scripted plug-in is cloned. This event handler is called on the newly created scripted plugin instance and the argument passed in is the plugin instance that was cloned.
EXAMPLE:
plugin material MyMaterial
name:"MyMaterial"
classID:#(0x69fedc0d, 0x7c79a4d2)
extends:Standard replaceUI:true
(
parameters hardwareShaders rollout:shaderRoll
(
)
rollout shaderRoll "Hardware Shaders" width:328 height:189
(
label l1 "AA"
)
on create do format "created: %\n"this
on clone orig do format "cloned: % : % : % : %\n" this orig(this == orig) (delegate == orig.delegate)
)
a=mymaterial()
b=copy a
RESULTS:
MyMaterial
created: (null):MyMaterial
MyMaterial:MyMaterial
cloned: MyMaterial:MyMaterial : MyMaterial:MyMaterial : false : false
MyMaterial:MyMaterial
Specific classes of scripted plug-ins implement additional event handlers and are described with description of the scripted plug-in type.
Runtime errors in certain event handlers cause the plug-in to be disabled until it is re-defined. When disabled, none of the plug-in event handlers are called. For example, errors in the map
event handler expression in SimpleMods
and the buildMesh
event handler expression in SimpleObject
disable the plug-in because they are called so frequently. You will need to correct any problems and re-evaluate the plug-in definition again to re-enable the plug-in event handlers.
on refAdded <caller> do ...
NEW in 3ds Max 2024:
Called whenever a reference is made to the scripted plugin object. The optional caller
is the object that has made the reference. In some cases caller
may be undefined
, because the object making the reference does not derive from ReferenceTarget.
For example:
plugin helper getsetHandlerTest
name:"DummyEx"
classID:#(1453456,5432110)
category:"Scripted Primitives"
extends:dummy
(
on refadded obj do format "refadded: %\n" obj
on refdeleted obj do format "refdeleted: %\n" obj
)
getsetHandlerTest()
--> refadded: $DummyEx:DummyEx001 @ [0.000000,0.000000,0.000000]
--> $DummyEx:DummyEx001 @ [0.000000,0.000000,0.000000]
delete objects[1]
--> refdeleted: <Deleted scene node>
on refDeleted <caller> do ...
NEW in 3ds Max 2024:
Called whenever a reference to this scripted plug-in is removed. The optional caller
is the object from which the reference to the plug-in object is removed. See the refAdded
example above.