MAXScript Language Reference > 3ds Max Objects > Animation Controllers > Controller Common Properties, Operators, and Methods >

# Controller Key Functions

Value > MAXWrapper > Controllers > Key Functions

| Animation Controllers - Quick Navigation

    addNewKey <controller> <time> [#select]

Adds a new key to the controller track at the time specified. The value for the new key is the interpolated controller value at the specified time. The new key is also selected if the #select optional argument is specified. The value for the new key is the interpolated controller value at that time. addNewKey() will not add a key if a key already exists at the specified time. The return value in this case is the key located at the specified time.

NoteIf the controller is a compound controller (like a Position_XYZ controller), a value of OK is returned. A single key value can’t be returned, as addNewKey creates a key in each of the sub-controllers.

This function returns a MAXKey value representing the key so you can set its various properties. See MAXKey Values for details.

    deleteKeys <controller> [#allKeys | #selection]

Deletes keys from the controller according to the optional symbolic argument supplied.

#allKeys (default): deletes all keys in the controller.

#selection : deletes the currently selected keys

    deleteKey <controller> <index>

Deletes the indexed key. Key indexes are 1- based.

    selectKeys <controller> [ <interval> | <time> ]

Selects the specified keys in the track view. If an interval is given, all the keys within the interval are selected. If a single time is given, the key at that time is selected. If no time or interval is given, select all keys.

    deselectKeys <controller> [ <interval> | <time> ]

Deselects specified keys. Arguments are as described in selectKeys() .

    selectKey <controller> <index_integer>

Selects the indexed key. Key indexes are 1- based.

    isKeySelected <controller> <index_integer>

Returns true if indexed key is selected, false otherwise. Key indexes are 1- based.

    deselectKey <controller> <index_integer>

Deselects the indexed key. Key indexes are 1 -based.

    moveKeys <controller> <time> [#selection]

Moves the specified keys by the time given. If #selection is specified, move the current selection otherwise move all keys. The moveKeys function only works on track properties, .controller and .track . It is not defined on the keys’ virtual array.

EXAMPLES
    moveKeys $box01.pos.controller 5
    moveKeys $box01.pos.track 5

    moveKey <controller> <index_integer> <time>

Move the indexed key by the specified time.

    numKeys <controller>

Returns the number of keys in the controller. Returns -1 if you call it on a controller that does not support keyframing.

    getKey <controller> <index_integer>

Returns the indexed key as a MAXKey instance. See Controller Key Functions for MAXKey class information.

    getKeyTime <controller> <index_integer>

Returns the time of indexed key.

    getKeyIndex <controller> <time>

Returns the index of the key at the specified time.

    numSelKeys <controller>

Returns the number of keys currently selected in the track view.

    sortKeys <controller>

Re-sorts keys according to their times. Some MAXKey operations can result in out of order keys and this function must be called to correctly order keys. See the Controller Keys and Key Properties topic for MAXKey properties information.

    createLockKey <controller> <time> <rot_or_pos_integer>

This method is called to create a locking key at the specified time. This is a key that looks back to the previous key and creates a new key at the specified time which matches the previous key in value. It also adjusts the parameters for the key such that the value stays constant from the previous key to this key. For instance, for a TCB controller the continuity of the previous key and new key will set to 0. For a Bezier controller the out tangent type of the previous key is set to linear and the in tangent type of the new key is set to linear.

If the controller passed to this method is a transform level controller, <rot_or_pos_integer> specifies whether to create the key in the transform controller’s position or rotation (or roll angle) sub-controller. If rot_or_pos_integer = 0, the key is created in the position controller. For all other values, the key is created in the rotation (or roll angle) controller.

If the controller passed to this method is not a transform level controller, the <rot_or_pos_integer> value is not used.

Returns true if the key creation was successful, false otherwise.

The following script shows example usages of some of the above methods.

EXAMPLES
    -- controller test bed 2
    b=box height:10
    at time 5 animate on b.height=50
    at time 10 animate on b.height=100
    bhc=b.height.controller
    bhk=bhc.keys
    addnewkey bhc 7
    addnewkey bhc 9
    for k in bhk do format "%:%\n" k.time k.value
    selectKeys bhc (interval 7 9)
    deleteKeys bhc #selection
    bhk
    addnewkey bhc 7
    addnewkey bhc 9
    selectKeys bhc (interval 7 9)
    deleteKeys bhc #selection #slide
    bhk
    addnewkey bhc 7
    addnewkey bhc 9
    selectKeys bhc (interval 7 9)
    deleteKeys bhc #selection #slide #rightToLeft
    bhk
    addnewkey bhc 8
    i=getKeyIndex bhc 8
    selectKey bhc i
    moveKey bhc i 10
    bhk
    getKeyTime bhc 4
    b.width.controller=noise_float()
    numkeys b.width.controller

    appendKey <key_array> <max_key>

Appends the given key to the specified key array at the key’s original time.

EXAMPLE
    --Create a Box and a Sphere
    source_obj = box()
    target_obj = sphere()
    -- Animate the position of the Box on frames 50 and 100.
    with animate on
    (
    attime 50 source_obj.pos.controller.x_position = 100
    attime 100 source_obj.pos.controller.x_position= 200
    )
    --Animate the position of the Sphere on frames 40 and 80
    with animate on
    (
    attime 40 target_obj.pos.controller.x_position = 50
    attime 80 target_obj.pos.controller.x_position = 60
    )
    --Print keys of both controllers
    format"Source Keys X Pos: %\n"source_obj.pos.x_position.controller.keys
    format"Target Keys X Pos: %\n"target_obj.pos.x_position.controller.keys
    --Get the 2nd key from the X axis controller of the position transformation
    source_key = source_obj.pos.x_position.controller.keys[2]
    --Get the X axis position controller keys array of the target object
    target_keys = target_obj.pos.x_position.controller.keys
    --Assign the key from the source to the target controller
    appendKey target_keys source_key
    --The Sphere now has a 3rd key on frame 50 with the value 100
    format "Target Keys After appendKey: %\n"target_obj.pos.x_position.controller.keys
OUTPUT
    $Box:Box02 @ [0.000000,0.000000,0.000000]
    $Sphere:Sphere02 @ [0.000000,0.000000,0.000000]
    200
    60
    Source Keys X Pos: #keys(0f, 50f, 100f)
    OK
    Target Keys X Pos: #keys(0f, 40f, 80f)
    OK
    #Bezier Float key(2 @ 50f)
    #keys(0f, 40f, 80f)
    #Bezier Float key(3 @ 50f)
    Target Keys After appendKey: #keys(0f, 40f, 50f, 80f)
    OK

    assignKey <key_array> <max_key> <index>

Deletes the key specified by <index> from the target key array and inserts the source key into the target key array at the source key’s time.

Note

Technically speaking, the source key first overwrites the target key specified by <index>, then the resulting array is being sorted by time. The result is the same as described above.

EXAMPLE
    --Create a Box and a Sphere
    source_obj = box()
    target_obj = sphere()
    -- Animate the position of the Box on frames 50 and 100.
    with animate on
    (
    attime 50 source_obj.pos.controller.x_position = 100
    attime 100 source_obj.pos.controller.x_position= 200
    )
    --Animate the position of the Sphere on frames 10 and 20
    with animate on
    (
    attime 10 target_obj.pos.controller.x_position = 50
    attime 20 target_obj.pos.controller.x_position = 60
    )
    --Print keys of both controllers
    format"Source Keys X Pos: %\n"source_obj.pos.x_position.controller.keys
    format"Target Keys X Pos: %\n"target_obj.pos.x_position.controller.keys
    --Get the 2nd key from the X axis controller of the position transformation
    source_key = source_obj.pos.x_position.controller.keys[2]
    --Get the X axis position controller keys array of the target object
    target_keys = target_obj.pos.x_position.controller.keys
    --Assign the key from the source to the target controller,
    --delete original sourcekey 3
    assignKey target_keys source_key 3
    --The Sphere now has a 3rd key on frame 50 with the value 100,
    --original 3rd key on frame 20 has been deleted:
    format"Target Keys After assignKey: %\n"target_obj.pos.x_position.controller.keys
LISTENER OUTPUT
    $Box:Box02 @ [0.000000,0.000000,0.000000]
    $Sphere:Sphere02 @ [0.000000,0.000000,0.000000]
    200
    60
    Source Keys X Pos: #keys(0f, 50f, 100f)
    OK
    Target Keys X Pos: #keys(0f, 10f, 20f)
    OK
    #Bezier Float key(2 @ 50f)
    #keys(0f, 10f, 20f)
    #Bezier Float key(3 @ 50f)
    Target Keys After assignKey: #keys(0f, 10f, 50f)
    OK

Note

appendKey and assignKey only work on controllers that directly support key frames and the source and target need to be of the same type. The controller level property<control>. supportsKeys (boolean, read-only) returns true if the controller implements the I_KEYCONTROL interface and thus can be used as argument of the appendKey and assignKey functions. See supportsKeys

In order to copy a key between controllers, the user has to

- Make sure that the source and target controllers are of the same type

- Check to see if they support keys using the. supportsKeys property

- If not, see if they have subanims

- If they have, recurse down into the subanims

- Repeat the check for the subanims and so on...

    copyPasteKeys <controller> (<map_struct> | <fn> <arg>) [#replacekeys] [#insertkeys]

This function is pretty similar to the existing mapKeys() method, but implies that some keys have been selected first. Upon calling copyPasteKeys(), selected keys will first get copied, then copied keys get selected and pasted, using either the map_struct or a mapping function as described in the mapKeys() method topic. Available in 3ds Max 8 and higher.

In addition, using the #replacekeys argument will delete any unselected key within the copied keys' range, and using the #insertkeys argument will shift to the right any unselected key located on or after the copied keys' insertion point (i.e., the location of the first copied key), with a time value equal to the length of the copied keys' range.

#### See Also

- Controller Time Functions

- Time and Key Functions on Object Hierarchies