Skip to main content

Text to motion

Generate high-quality 3D character animations from simple text prompts. Text-to-motion is perfect for quickly creating animations without needing video input or motion capture data.

Overview

Text-to-motion allows you to describe an animation in natural language, and Uthana will generate a motion sequence that matches your description. Results are returned immediately—no polling required.

Step-by-step tutorial

Step 1: Authenticate your request

First, ensure you have your API key ready. You'll use it to authenticate all requests to the Uthana API.

# Set your API key
API_KEY="{{apiKey}}"

Step 2: Generate motion from text

Create a text-to-motion animation by sending a mutation with your text prompt.

curl -X POST https://uthana.com/graphql \
  -u $API_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation CreateTextToMotion($prompt: String!) { create_text_to_motion(prompt: $prompt) { motion { id name } } }",
    "variables": { "prompt": "a person walking down the street" }
  }'

Step 3: Handle the response

Text-to-motion results are returned immediately. The response includes the motion ID and name.

{
  "data": {
    "create_text_to_motion": {
      "motion": {
        "id": "m3G3XSJrjEJH",
        "name": "a person walking down the street"
      }
    }
  }
}

Step 4: Download your motion

Once you have the motion ID, you can download it in FBX or GLB format. You'll need both the character ID and motion ID.

CHARACTER_ID="cXi2eAP19XwQ"  # Default character, or use your own
MOTION_ID="m3G3XSJrjEJH"

# Download as FBX (filename is customizable)
curl -L "https://uthana.com/motion/file/motion_viewer/$CHARACTER_ID/$MOTION_ID/motion.fbx" \
  -u $API_KEY: \
  -o motion.fbx

# Download as GLB (filename is customizable)
curl -L "https://uthana.com/motion/file/motion_viewer/$CHARACTER_ID/$MOTION_ID/motion.glb" \
  -u $API_KEY: \
  -o motion.glb

# Download at specific FPS (24, 30, or 60)
curl -L "https://uthana.com/motion/file/motion_viewer/$CHARACTER_ID/$MOTION_ID/motion.fbx?fps=30" \
  -u $API_KEY: \
  -o motion-30fps.fbx

Advanced options

Enable foot IK

For better foot placement on uneven surfaces, enable foot IK:

curl -X POST https://uthana.com/graphql \
  -u $API_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation { create_text_to_motion(prompt: \"walk casually\", foot_ik: true) { motion { id name } } }"
  }'

Try Uthana's BUCMD model

For more control over generation parameters, use the text-to-motion-bucmd model:

curl -X POST https://uthana.com/graphql \
  -u $API_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation { create_text_to_motion(prompt: \"confident stride\", model: \"text-to-motion-bucmd\") { motion { id name } } }"
  }'

BUCMD advanced options

The text-to-motion-bucmd model supports additional parameters for fine-tuning generation:

  • foot_ik (Boolean): Enable foot IK for better foot placement on uneven surfaces. Defaults to false if not specified.
  • steps (Int): Number of diffusion steps. Range 1–150, default 50.
  • cfg_scale (Float): Classifier-free guidance scale. Range 0–10, default 2.
  • length (Float): Desired motion length in seconds. Range 0.25–10, default 10.
  • motion_length (Int): DEPRECATED. Use length instead. Desired motion length in frames (20 FPS).
  • seed (Int): Random seed for reproducibility. Range 1–99999, default None (random).
  • retargeting_ik (Boolean): Enable inverse kinematics (IK) for retargeting from the internal skeleton. Defaults to true if not specified (it is recommended to keep this enabled for best results).

Example with advanced options:

curl -X POST https://uthana.com/graphql \
  -u $API_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation CreateTextToMotion($prompt: String!, $model: String, $steps: Int, $cfg_scale: Float, $length: Float, $seed: Int, $retargeting_ik: Boolean) { create_text_to_motion(prompt: $prompt, model: $model, steps: $steps, cfg_scale: $cfg_scale, length: $length, seed: $seed, retargeting_ik: $retargeting_ik) { motion { id name } } }",
    "variables": {
      "prompt": "confident stride",
      "model": "text-to-motion-bucmd",
      "steps": 50,
      "cfg_scale": 2.0,
      "length": 10,
      "seed": 12345,
      "retargeting_ik": true
    }
  }'

Error handling

If something goes wrong, check the errors array in the response:

# Check for errors in response
if echo "$RESPONSE" | jq -e '.errors' > /dev/null; then
    echo "Error occurred:"
    echo "$RESPONSE" | jq '.errors'
fi

Next steps