Nubu
  • Features
  • How it works
  • Pricing
  • Integrations
  • FAQ
  • Contact
  • Docs
  • Blog
  • Log in
  • Log inSign up
    Nubu

    Creative automation for teams that ship campaigns, not busywork.

    Try for free
    Product
    FeaturesNubu MotionHow it worksPricingIntegrationsFAQ
    Company
    AboutContactDocsBlogLog in
    Legal
    Privacy policyTerms of serviceData deletion
    © 2026 Bear Studios · Nubu
    Introduction
    Templates overviewInstalling Nubu BuilderAdding template compsAdding propertiesAdding footageSetting defaultsExporting your templateUploading a template
    Flows overviewAvailable nodesAdding a nodeConnecting nodesWorking with dataTemplates and outputsUsing AI nodesBuilding a creative
    CampaignsTemplatesAssetsGlossariesRendersSettings
    Connecting Meta AdsConnecting Google AdsConnecting OpenAIConnecting Gemini AI StudioConnecting Anthropic
    AI Assistant overviewPrompt examplesAssistant settings and controls
    Nubu Motion scripts: the reference
    OverviewQuick startDifferences from After EffectsDeterminism
    JavaScript supportReferences and idsProject scriptsState and timeBudgets and errorsFormatting values
    GlobalTime conversionInterpolationVector mathsRandom and noiseColour conversionOther maths
    LayerCompPropertyKeyframePathGeometryProjectComponentConsoleComponentControlExpressionControl
    The property vocabularyAnimators propertiesAudio propertiesContent propertiesContents propertiesEffects propertiesExpression controls propertiesFills propertiesInstance controls propertiesLayer propertiesLayout propertiesMasks propertiesStrokes propertiesText style propertiesRig propertiesRigging propertiesRig controllers propertiesRigging weights propertiesRigging mesh propertiesRig items propertiesRig splines propertiesRig simulation propertiesRig properties propertiesRig drivers propertiesRig draw order propertiesTransform propertiesTrim path properties
    Error codesBudgets
    Changelog
    All docs
    Motion Scripting
    / Properties

    Rig controllers properties

    A rig layer's controller channels by controller id: position, rotation and scale - the handles an IK target or a constraint follows.

    The rig controllers family: a rig layer's controller channels - position (px in the parent's frame: a bone's tip, a controller, or rig space), rotation (degrees) and scale (percent, 100 = 1:1) - addressed by controller id. Every pattern reads, keyframes AND drives: a script moving an IK target controller solves the chain that reaches for it, which is the scripted foot plant.

    Every pattern below is readable from scripts through prop() and layer.prop(); ids in a pattern (like <effect_id>) stand for the entity's real id. Every pattern here is in the drive set: scripts may WRITE each one with set() or a single-output return, per frame.

    PatternWire kindUnitsReadsWrites
    rig.controllers.<controller_id>.positionpoint2[x, y] px (in the parent frame: a bone's tip frame, a controller's frame, or rig space for a root)yesdrive set
    rig.controllers.<controller_id>.rotationscalardegreesyesdrive set
    rig.controllers.<controller_id>.scalepoint2[x, y] percent (100 = 1:1)yesdrive set

    Worked examples#

    A rig layer's CONTROLLERS are its posable handles (RIG-W2 CONTROL): each is addressed by its own id - rig.controllers.<controller_id>.position ([x, y] px in the parent frame: a bone's tip frame, a controller's frame, or rig space for a root), .rotation (degrees) and .scale ([x, y] percent). The id comes from the scene (the Scripts panel and the @ pick whip write it for you). Every channel reads, keyframes AND drives - a driven target moves the IK chain that reaches for it, exactly as a dragged one does.

    Worked example: Glide the foot target#

    The scene. A Stage comp with a two-bone Leg rig - the Thigh hanging down from (320, 60), the Shin under it - whose IK item on the Shin reaches for the Foot controller (parked up and to the left of the rest tip) with the Knee controller as its pole, and a Foot pad solid rigidly bound to the Shin.

    • The comp Stage: 640 by 360 at 25 fps, 100 frames (4 seconds).
    • Leg: a rig layer.
      • The skeleton: Thigh (bone_1, a root) from [320, 60] at 90 degrees for 100 px; Shin (bone_2, under Thigh) at 0 degrees for 80 px.
      • The controllers: Foot (ctrl_1, rig space) at [220, 140], a diamond; Knee (ctrl_2, rig space) at [420, 150].
      • The items: rigging_1 - an IK item on the Shin reaching for the Foot (chain 2, pole the Knee).
    • Foot pad: a solid layer, at [300, 240], 60 by 40, filled #4d9de0.
      • The rigging stack: rigging_2 - a rigid binding to the Leg rig's Shin.

    The script. Add a project script named Foot glide and paste:

    export const outputs = ["layer_1:rig.controllers.ctrl_1.position"];
    
    export function frame() {
      return [linear(time, 0, 4, 320, 220), linear(time, 0, 4, 240, 140)];
    }
    

    Line by line:

    • Line 1: One output: the Foot controller's POSITION on the Leg rig. A controller channel is addressed like any other property - rig.controllers.<controller_id>.position - and its value is a point, [x, y] in the parent frame's px (rig space here: the Foot is a root, so these are the rig layer's own px).
    • Line 4: Two linear() ramps, one per axis, glide the target from the leg's rest tip (320, 240) up and to the left to (220, 140) over the first four seconds and hold there. The IK item on the Shin reaches for the target every frame, so the leg bends as the target travels; the controller's own authored position is dormant while the script drives (the row keeps it with the script marker).

    What you see. The Foot target glides from the leg's rest tip up and to the left over four seconds; the two-bone leg bends to keep its tip on the target and the bound Foot pad rides the shin - at one second the target reads (295, 215).

    The Foot target glides from the leg's rest tip up and to the left over four seconds; the two-bone leg bends to keep its tip on the target and the bound Foot pad rides the shin - at one second the target reads (295, 215).