Phone: 905 409-1589
Email: info@penproductions.ca
RSS LinkedIn Twitter Twitter
Custom Attributes
Calling Custom Attributes from Script Controllers:
Custom Attributes (CA) in max are used to create spinners menus and other interface items that can be added to nodes in the modifier stack like the Attribute Holder modifier. This isn't the only use for them if you know your way around max script (MXS). Scripting your our CA's is just the same as scripting plugins and has a huge amount of flexibility to what can be achieved. Instead of just creating interface items, functions, event handlers, structs and anything else you can do with MXS can be added to a CA definition and then added to any node in the scene. A scene node could mean an object like a sphere, a modifier or even a controller like a script controller.

One thing that I have been using CA defs for is stores functions that I need to call from script controllers. I could write that code into each script controller but if I have the same piece of code used in many script controllers it is a pain to setup and maintain if there are any changes. You could write the function and save it to a .ms file in the stdPlugs\stdScripts folder and have it load locally but then you have to make sure that all the computers that will be using the script are loading it. The advantage to this is if many different objects in many different files are going to use this code it is easy to up date all of them by just changing one script.

I have run into cases where I have a custom function that will only be used by one character lets say. So that I know the function is loading with the character I store that function in a CA definition and add that definition to an object in the characters rig. I can then call that function from that object and execute the operation in the function as needed. The following is how I go about doing that.

This example will set up a car wheel that rolls when the wheel moves along the world X axis

Create a custom attribute definition that will hold the function. We will be able to call this function for all four wheels on our car without having to rewrite it. This is a simple example of a function that could be used.

Code:
--Create a custom attribute definition
ca=attributes myCaDef
(
--Function for calculating the roll of a wheel
fn wheel v r=
(
c=(2*pi*r) --Circumference of the wheel
deg=(c/6.28319) --c / Radians
rot=v/deg --Position / deg
rot --This isn't really needed
)
)

Create a control object where we will store the CA definition. This would be some master control object at the top of the hierarchy most likely that the animator could select to set master values for the cars control.

Code:
--Create a control circle that will store the CA def.
cir=circle name:"Master"
--Add the CA def to the control.
custAttributes.add cir ca

Position and rotate the wheel so that it sits on the floor.

Code:
--Create a cylinder to act as the wheel.
cyl=cylinder radius:30 height:10 name:"Wheel"
rotate cyl (eulerAngles 90 0 0)
move cyl [0,0,30]

Apply a script controller to the Y rotation axis of the wheel and write the script. The script calls on the master control object and then the wheel function that is stored in the CA def that is on the master control. It also passes the two variables the wheel function needs. The function returns the value that the wheel should rotate based on the position of the wheel.

Code:
--Apply a script controller to the y rotation of the wheel.
sCon=cyl.rotation.y_rotation.controller=float_script()
--Write the script controller, notice it --is calling on the function stored in the control.
sCon.script="$master.myCaDef.wheel $wheel.pos.x $wheel.radius"

Here I am just animating the wheel moving forwards along the X axis for demonstration of this working.

Code:
--Animate the wheel for demonstration.
animate on
at time 100 move cyl [200,0,0]

Down load the script: custAttributes.ms