Maya Keyframe Randomizer

This is a Maya python script used for randomizing keyframe values or times. When applied over a range, a different randomization will be applied to each attribute and each key for it. Using the GUI you can select what attributes to modify, whether to modify them in space and/or time, and the ranges for modification. First, copy&paste this into the script editor, select all of it, and save it to your shelf. Then, select the objects you want to adjust their keyframes and run the script.

The first two checkboxes are for space / time modification. Spatial Keyframes will modify attribute values for each keyframe. Temporal Keyframes will modify the frame that the keyframes are on.

Min / Max Randomness is the amount to be applied to each value. The amount is added, so 0-1 will only produce positive alterations and -1-0 will only produce negative alterations. The value is a floating point number, so 0-1 will always randomly  choose a decimal in between.

Start / End Frames is the frame range for randomization to happen. Anything outside of this range will not be affected.

The list of values to change are on the right side. Every value checked will be randomized in the frame range specified by the amount specified. If you choose a master box, such as translation, it will affect the three associated boxes equally, like translateX Y and Z. So selecting translate and translateY will randomize all translate values and then only translateY afterwards.

If you need to edit any additional attributes, you can add them in the attributes[] list near the top of the script. Keep in mind, if all selected objects don’t have the attribute or you don’t call it exactly as PyMEL calls the attributes, the script might error out.

NOTE: This script requires PyMEL. To use this script, you should paste the following into the Python section of the Script Window, and then execute the code. Or you could drag the selected code in the Python tab to the Shelf to create a shelf item for it.

## This script requires pymel

## This script offers a way of randomizing many
## objects' keyframes in time and space
## You can select individual channels or their master channel

## Import pymel and the random module
from pymel.core import *
import random

## ---- VARIABLES ---- ##

## List of attributes to modify
attributes = ['translateX', 'translateY', 'translateZ', 'translate', 'rotateX', 'rotateY', 'rotateZ', 'rotate', 'scaleX', 'scaleY', 'scaleZ', 'scale', 'visibility']
## New blank dictionary
attributeBoxes = {}
## New blank list
attributesToChange = []

## ---- FUNCTIONS ---- ##

## Given a minimum and a maximum value, it checks
## if the minimum is actually lower than the maxmimum
## Equal values are okay, because then someone just
## wants to increase/decrease all values equally
def checkValues(min, max):
    if min > max:
        informBox("Error", "Your minimum value is higher than your maximum value", ok="Okay.")
        return False
    else:
        return True

## Creates a new list of all the attributes to modify
def createList():
    tempAttribs = []
    ## For each attribute and corresponding checkbox
    for attr, box in attributeBoxes.iteritems():
        ## If the box was checked and returned True
        if box.getValue() is True:
            ## Append the key name to the modify list
            attributesToChange.append(attr)

## Gets all of the values from the GUI
def randomize():
    ## Prints the values from the checkboxes
    createList()
    ## Create a tuple of the time range
    timeFrame = (minFrame.getValue(), maxFrame.getValue())
    ## Get the selection
    selected = ls(selection=True)
    ## For each object in the selection
    for object in selected:
        ## And each attribute for the object
        for attribute in attributesToChange:
            ## Get the list of keys of that attribute in the time range
            keyList = keyframe(object+"."+attribute, time=timeFrame, query=True)
            ## For each key
            for key in keyList:
                ## Depending on what should change
                ## Change the objects attribute to a new random value
                ## The value is relative to it's current value
                if spaceRand.getValue() is True:
                    changeAmount = random.uniform(maxRand.getValue(), minRand.getValue())
                    keyframe(object+"."+attribute, valueChange=changeAmount, relative=True, time=(key, key))
                if timeRand.getValue() is True:
                    changeAmount = random.uniform(maxRand.getValue(), minRand.getValue())
                    keyframe(object+"."+attribute, timeChange=changeAmount, relative=True, time=(key, key))
    deleteUI(gui, window=True)

## The function to call whenever the user pressed the button
def startRandomization(*Args):
    ## If both number ranges are fine, continue
    if checkValues(minRand.getValue(), maxRand.getValue()) is not False:
        if checkValues(minFrame.getValue(), maxFrame.getValue()) is not False:
            randomize()

## ---- GUI SECTION ---- ##
## Makes a flow layout to arrange two columns side by side
gui = window(title="Key Randomizer", width=440)
mainLayout = flowLayout()
col01 = columnLayout(rowSpacing=5, parent=mainLayout, width=220)
col02 = columnLayout(rowSpacing=5, parent=mainLayout, width=220)

separator(h=20, parent=col01)

text(label="Which keyframes to randomize?", parent=col01)
spaceRand = checkBox(label="Spatial Keyframes", value=False, parent=col01)
timeRand = checkBox(label="Temporal Keyframes", value=False, parent=col01)

separator(h=20, parent=col01)

text(label="Min / Max Randomness", parent=col01)
minRand = floatField(value=-.5, parent=col01)
maxRand = floatField(value=.5, parent=col01)

separator(h=20, parent=col01)

text(label="Start / End Frames", parent=col01)
minFrame = intField(value=1, parent=col01)
maxFrame = intField(value=48, parent=col01)

separator(h=20, parent=col01)

goButton = button(label="Go!", command=startRandomization, parent=col01)

separator(h=20, parent=col02)

## For each item in the list of attributes, add a checkbox
## And store the name of the value as the key and the checkbox
## As the value in the blank dictionary we created earlier
for attribute in attributes:
    attributeBoxes[attribute] = checkBox(label=attribute, value=False, parent=col02)

gui.show()

One Response

  1. emad
    emad at · Reply

    Cool Man ! 🙂
    Thank you
    i have a question and need some directions.
    i wanna write a script in mel that make a dance for my character but i don’t have any idea about it . have you ever did some thing like this before ? pls let me know your idea.
    this my email : emad.tayefeh@gmail.com

Leave a Reply