Referencing Nodes and Controllers in Script Controllers FAQ

 

   

Animation Controllers - Quick Navigation

The following Questions and Answers discuss the various variable types available in Script Controllers in 3ds Max 8 and higher.

What is the difference between the new and the old script controllers?

The main difference between the old script controllers available prior to 3ds Max 8 and the new ones in 3ds Max 8 and higher is that there is an "Assign Node" button that allows you to pick a node.

What is special about this is that the node is not held as a direct reference of the script controller, rather it is held as in indirect reference. This is done through an intermediate class called NodeTransformMonitor.

The only messages that propagate from the referenced node to the scripted controller are node transform messages and node deletion messages. This allows you to place a scripted controller on a sphere's radius track, and then in the scripted controller have a variable pointing at the node holding the sphere without creating a circular dependency.

Note that the expression controller also uses the NodeTransformMonitor when you have a variable pointing at a node.

See Also Script Controller - Avoiding Circular Dependency

What can I assign through the Assign Constant button?

If you click Assign Constant, you can type in any valid MAXScript expression. If the result is a MAXWrapper (like a node, material, modifier, controller etc.), the result is stored as an Object. If the result is a subAnim, it is stored as a Target.

You can assign either a constant value from a MAXScript expression, or a dynamic value if the expression evaluates to a controller.

If you create the variable myVar and use the Assign Constant button to assign the expression

$Box01.position.x_position.controller.value

in the Assign Constant dialog, the value of the controller on the current frame will be taken as a constant value and assigned to the variable myVar.

But if you say

$Box01.position.x_position.controller

this will create an Object value that points at the controller. In the controller's expression code, you can use 'myVar.value' to get the current value. The value will not be stored as a constant, but will be dynamic and change as the current time changes.

What is the difference between assigning an Object and a Node to a variable?

Let's say that you have two scripted controllers X and Y, and a node N that has a sphere base object. A variable in X points at N as an Object. A variable in Y points at N as a Node. If you change the sphere's radius, only X is re-evaluated. If you move N, both X and Y are re-evaluated.

If stored as a Node value, the controller is invalidated only if the node's transform changes or the node is deleted. But it does allow you to specify nodes that would create a circular reference if specified as an Object value.

To specify whether to store an Object or a Node, you should use the Assign Track / Assign Node buttons, or the MAXScript methods. When using the Assign Constant expression, a MAXWrapper will always be stored as Object.

What is the difference between accessing an object property through Node and Object

If you want, you can just create variables that hold Nodes as Object values, and then reference the parameter you want as you would normally in the expression. For example, myNode would point at a sphere node, and your expression would be "myNode.radius". But this is not going to have as good performance as pointing to the sphere's radius track as a Target. In the former, any change to the node (for example, moving the node) will result in a controller re-evaluation. In the latter, only changes to the sphere base object will result in a controller re-evaluation.

Also, if you just specify a Node variable and then access base object parameters on it (for example, its radius), you will get an error if you bring in the node as an XRef. An XRef object doesn't expose the properties of the object it wraps, so there is no 'radius' parameter. Thus an error will be generated when the expression is evaluated. If you point a variable at the sphere's radius track and use that variable instead, the expression will still work when XRef-ed in.

What is the difference between using explicit paths names in the Expression (like in releases prior to 3ds Max 8) and using the new variables pointing at nodes?

There are multiple important differences.

Let's say you have an object $Sphere01 using a script controller pointing at an object called $Box01.

$Box01.position.x_position.controller

every time the expression is evaluated MAXScript needs to resolve the node name 'Box01' to a node value, resolve the position property to the position controller, resolve the x_position property to the x_position subAnim, get the controller from the subAnim, and get the MAXScript MAXControl value wrapping the controller.

If you had a Target variable pointing at the controller, all that needs to happen is to get the MAXScript MAXControl value wrapping the controller.

Should I use dependsOn in the new Script Controller?

You do not need 'dependsOn' in the scripted controller's expression since 3ds Max 8.

'dependsOn' should not be used in new scripts, and should actually be removed from old ones.

When you have 'dependsOn' in a script controller expression, a new variable will be automatically created (Depends_#) that points at the node as an object. This will cause all changes to the node to result in a script controller re-evaluation.

The automatic creation of the dependson_# variable is a special case. It is created based on the 'dependsOn' command being executed and by definition the arguments to dependsOn are MAXWrapper objects.

This is also needed to ensure that existing script controllers using 'dependsOn' would continue to work correctly without tweaking the controller.

See Also