The MetaHuman Character Python API exposes the operations needed to create, edit, conform, sculpt, assemble, and export MetaHuman Character assets from scripts and Editor Utility Blueprints.
This page describes the structure of the API, the editor subsystem that drives most operations, and the patterns you use to apply edits and commit them to a character asset.
The API was designed for Python, but the same functionality is available from Editor Utility Blueprints.
Overview
The MetaHumanCharacter asset represents a MetaHuman Character. The asset stores all data for a single character: face state, body state, skin, eyes, makeup, viewport settings, and the slot-based wardrobe collection.
Two distinct surfaces work together:
The
MetaHumanCharacterasset. Many properties (skin, eyes, makeup, viewport settings, and the internal wardrobe collection) can be read and written directly on the asset without opening it for editing.The
MetaHumanCharacterEditorSubsystem. Required for interactive edits such as face landmark manipulation, body sculpting, conform, texture and auto-rig requests, and assembly. It also drives the live viewport when a character is open in the editor.
Most non-trivial workflows follow the same pattern - register the character for editing with the subsystem, perform edits, commit each change so it is reflected in the live viewport and serialized to the asset, then remove the character from the subsystem when done.
Prerequisites
A project running Unreal Engine 5.8 or later.
The MetaHuman Character plugin enabled.
Python scripting enabled for the Unreal Editor.
Reference Scripts
Reference scripts ship with the plugin at Engine/Plugins/MetaHuman/MetaHumanCharacter/Content/Python/.
examples/contains runnable scripts for the common workflows described on this page. Each script focuses on a single task.The parent
Python/folder containstest_*.pyfiles that exercise the API more thoroughly. Use these as supplementary references when an example script does not cover the property or pattern you need.
The MetaHuman Character Asset
You can edit any writable property on MetaHumanCharacter directly, without registering the asset with the editor subsystem. This includes:
Eye properties (iris, pupil, sclera, and per-eye overrides) through
eyes_settings.Makeup properties (blush, eye makeup, foundation, and lips) through
makeup_settings.Viewport settings (camera framing, environment, lighting, level of detail, and overlays) through
viewport_settings.The preview material type through
preview_material_type.
For a complete enumeration of the writable properties, see test_set_character_properties.py. For an example of creating a new asset from Python, see examples/example_create_asset.py.
When to use direct writes vs. commit functions. Direct property writes on the asset (for example, character.eyes_settings = ... or character.makeup_settings = ...) serialize immediately to the asset and are the right choice for headless or batch scripts that do not open the character in the editor. The corresponding commit functions on the subsystem (commit_eyes_settings, commit_makeup_settings, commit_skin_settings) are required when the character is open in the editor and the viewport must refresh, or when the change needs to participate in the same staged state as subsystem-side edits, such as face landmarks or body constraints.
The MetaHuman Character Editor Subsystem
MetaHumanCharacterEditorSubsystem is an editor subsystem accessed through unreal.get_editor_subsystem(unreal.MetaHumanCharacterEditorSubsystem). It owns the per-character state needed for interactive edits and is required for face and body operations, texture and auto-rig requests, and assembly.
Opening a character in the editor automatically registers it with the subsystem. When working from a script that does not open the editor, you must register the character explicitly.
The core registration functions are:
| Subsystem Function Name | Description |
|---|---|
| Tries to load a MetaHuman Character asset to be edited. The subsystem will create and track all data needed to perform edits to the character. Note that opening a MetaHuman Character asset editor will also call this function as the character has to be registered in the subsystem. |
| Removes an object from the subsystem. This is important to character specific data that the subsystem is holding. Note that closing a MetaHuman Character asset editor will also remove it from the subsystem. |
| Checks if a character is registered for editing in the subsystem. |
A typical script that operates on a character not open in the editor follows this pattern:
character = unreal.load_asset("/Game/Characters/MetaHumans/Jeff.Jeff")
subsystem = unreal.get_editor_subsystem(unreal.MetaHumanCharacterEditorSubsystem)
if not subsystem.try_add_object_to_edit(character):
raise RuntimeError("Unable to edit asset, is it already open for edit?")
try:
# ... edits and commits go here ...
pass
Commit Changes
Operations that go through the subsystem update an internal preview state, not the asset itself. To make a change visible in the open viewport (and to serialize the change onto the asset), call the corresponding commit function for that domain:
Face state (landmarks, model coefficients):
commit_face_state(character)Body state (parametric constraints):
commit_body_state(character)Eyes:
commit_eyes_settings(character, eyes_settings)Makeup:
commit_makeup_settings(character, makeup_settings)Skin:
commit_skin_settings(character, skin_settings)Other head model sub-systems (teeth, eyelashes):
commit_head_model_settings(character, head_model_settings)
The two calling conventions are not interchangeable. commit_face_state and commit_body_state take only the character, because the new state was already staged on the subsystem through earlier calls like translate_face_landmarks, set_face_model_coefficients, or set_body_constraints. commit_eyes_settings, commit_makeup_settings, commit_skin_settings, and commit_head_model_settings take a pre-built settings struct as their second argument, because eyes, makeup, skin, and head-model state are constructed Python-side as standalone structs rather than mutated incrementally through the subsystem.
For an example, see examples/example_live_edit.py. Select a MetaHuman Character asset in the Content Browser, run the script, and observe the face edits applied to the open editor after each commit.
Download Textures and Auto-Rig
The subsystem exposes two requests against the MetaHuman Cloud services:
request_texture_sources(character, params)downloads high-resolution texture sources for the character.request_auto_rigging(character, params)runs auto-rigging on the character's face.
Both requests take a parameter struct that controls whether the call is blocking and whether progress is reported:
request_texture_sourcesusesMetaHumanCharacterTextureRequestParams. Setblocking = Trueandreport_progress = Falseto run synchronously in batch contexts.request_auto_riggingusesMetaHumanCharacterAutoRiggingRequestParams. In addition to blocking andreport_progress, setrig_typeto one ofMetaHumanRigType.JOINTS_ONLYorMetaHumanRigType.JOINTS_AND_BLENDSHAPES.
For full examples, see examples/example_download_textures.py and examples/example_auto_rig.py. To remove the face rig after auto-rigging, call remove_face_rig(character). This removes the rig but does not reset the face mesh.
Cloud Service Behavior
request_texture_sources and request_auto_rigging call MetaHuman Cloud services.
Authentication
The editor must be signed in to an Epic account with MetaHuman Cloud access. Sign-in is handled by the editor; the first request_auto_rigging call against a session triggers the sign-in flow. Once signed in, request_texture_sources uses the same authentication.
Run scripts with blocking = True. This is the supported pattern for batch and commandlet contexts:
auto_rigging_request = unreal.MetaHumanCharacterAutoRiggingRequestParams()
auto_rigging_request.blocking = True
auto_rigging_request.report_progress = False
auto_rigging_request.rig_type = unreal.MetaHumanRigType.JOINTS_ONLY
subsystem.request_auto_rigging(character, auto_rigging_request)The call returns only after the cloud operation completes or fails. HTTP, authentication, and timer subsystems continue to tick during the wait.
Configure Outfits and Grooms
Grooms and clothing are applied through the MetaHuman Pipeline slot system. Each wardrobe item belongs to a named slot, such as Hair for grooms or Outfits for clothing.
To add a wardrobe item to a character:
Load the wardrobe item with
unreal.load_asset.Call
character.internal_collection.try_add_item_from_wardrobe_item(slot_name, wardrobe_item)to register the item in the collection. The return value is aMetaHumanPaletteItemKey.Construct a
MetaHumanPipelineSlotSelectionwith the slot name and the item key.Call
character.internal_collection.default_instance.try_add_slot_selection(selection)to select the item for the character.
For complete examples, see examples/example_add_grooms.py and examples/example_add_clothing.py.
Editing Wardrobe Item Parameters
Each wardrobe item exposes a set of instance parameters, such as hair Melanin or outfit PrimaryColorShirt. You read and write instance parameters on the character's collection, but the parameter list is only populated after the assemble_for_preview call runs.
To edit instance parameters on a wardrobe item:
Register the character with
try_add_object_to_edit.Call
assemble_for_preview(character)to populate the parameter list.Build a
MetaHumanPaletteItemPathfrom the wardrobe item'sMetaHumanPaletteItemKey.Call
character.internal_collection.default_instance.get_instance_parameters(item_path)to retrieve a list ofMetaHumanCharacterInstanceParameterobjects.Locate parameters by name and update them with
set_bool,set_float, orset_coloras appropriate to the parameter's type.
For an alternative pattern that works through get_preview_collection and propagates edits back with on_edit_preview_collection, see test_set_character_instance_params.py. That pattern is required when edits must survive a subsequent pipeline rebuild.
Conform the Head
Head conform replaces the character's face geometry with a target shape. Several paths import from a .dna file, the MetaHuman rig format that packages mesh, joints, skin weights, and RBF (radial basis function) solver data into a single deterministic asset. Each path has its own parameter struct.
The functions below register the conformed face state. After conforming, call commit_face_state(character) if the change must be reflected in an open viewport.
| Function | |
|---|---|
| Conforms from a .dna file on disk. Uses |
| Conforms from a face skeletal mesh asset with MetaHuman topology. Uses |
| Fits from per-region vertex arrays for head, teeth, and eyes. Uses |
| Conforms from a |
For the ImportErrorCode returning functions, check the result against ImportErrorCode.SUCCESS and handle other codes explicitly.
For the DNA, template, and vertex-fit paths, see examples/example_conform_head.py. For the Identity path, see examples/example_conform_from_identity.py.
Conform the Body
Body conform supports four paths. Pick the one that matches your input:
| Path | Description |
|---|---|
Stepwise template conform | For a MetaHuman-topology skeletal mesh. Three-call pipeline that exposes the mesh and joint arrays before the solver runs, so you can inspect or modify them. |
Stepwise DNA conform | Same shape as the template path, but the inputs are .dna file paths instead of skeletal mesh assets. |
Whole-rig DNA import | For a body .dna file. Imports verbatim with no fitting. Produces a fixed (non-editable) body. |
End-to-end conform from a custom mesh | For a custom (non-MetaHuman-topology) mesh plus a front-facing portrait image. Combines body conform with face landmark tracking driven by the portrait. |
For projects upgrading from Unreal Engine 5.7, see Migration Notes at the end of this page.
Stepwise Conform from a Template Mesh
For callers that need to conform the body from a template skeletal mesh with MetaHuman topology, the stepwise path exposes three functions:
get_mesh_for_body_conforming_from_template(character, body_mesh, face_mesh, match_vertices_by_u_vs). Returns the body vertex array.get_joints_for_body_conforming_from_template(body_mesh). Returns the joint translations and rotations.conform_body_to_target(character, vertices, joint_rotations, target_is_in_a_pose, estimate_joints_from_mesh). Applies the conform.
conform_body_to_target returns a bool. Set target_is_in_a_pose = True if the input mesh and joint rotations are already in MetaHuman A-pose; the solver uses this to skip the repose step. Set estimate_joints_from_mesh = True to estimate joint positions volumetrically from the mesh vertices.
For a full example, see examples/example_conform_body_from_template.py.
To bypass the solver entirely, set the body mesh and joints directly with set_body_mesh(character, vertices, reposition_helper_joints) and set_body_joints(character, translations, rotations, import_helper_joints).
Stepwise Conform from DNA
The DNA stepwise path mirrors the template path but takes .dna file paths instead of skeletal mesh assets. Use it when your input is a MetaHuman-topology body DNA file.
get_mesh_for_body_conforming_from_dna(character, body_dna_path, head_dna_path). Returns the body vertex array. The head DNA path is optional and falls back to the character's own face DNA if omitted.get_joints_for_body_conforming_from_dna(body_dna_path). Returns the joint translations and rotations.conform_body_to_target(character, vertices, joint_rotations, target_is_in_a_pose, estimate_joints_from_mesh). Applies the conform - the same call used by the template path.
For a full example, see examples/example_conform_body_from_dna.py.
Whole-Rig Import from DNA
import_body_whole_rig(character, body_dna_path, head_dna_path) imports the body (and optionally the head) directly from .dna file paths as a fully-rigged, fixed (non-editable) body. Mesh, joints, RBF solver data, and skin weights are taken verbatim from the DNA; no fitting is performed. The DNA must use MetaHuman body topology and must be body-only. Combined DNA is not accepted. The head DNA argument is optional; pass an empty string to skip.
For an example, see examples/example_conform_body_whole_rig_from_dna.py.
End-to-End Conform from a Custom Mesh
conform_to_target_meshes combines body conform with face landmark tracking on a portrait image. The 2D landmarks extracted from the image drive the 2D landmark term of the solve.
The pipeline has the following stages:
Load a pre-rendered front-facing portrait into a pixel array with
unreal.PromotedFrameUtils.get_promoted_frame_as_pixel_array_from_disk.Run
track_face_landmarks_from_image(pixels, width, height)to extract 2D facial contour curves.Load the target mesh and extract topology with
get_mesh_data_for_conforming(target_mesh).Build a
ConformTargetParamsstruct containing the mesh data, the curve tracking points, and theMinimalViewInfofor the camera that produced the portrait.Call
conform_to_target_meshes(character, target_mesh_key, params)to fit body and face state. The function returns a bool.
The portrait must be pre-rendered, and the camera intrinsics and extrinsics supplied to the solver must match the camera that produced the image, because the 2D landmarks are back-projected into 3D during the solve.
For a full example, including optional keypoint pinning, posed DNA export, and committing the conformed pose as the A-pose, see examples/example_conform_from_custom_mesh.py.
Sculpt the Face
The face supports two sculpting modes.
Landmark Manipulation
Translate face landmarks by per-landmark deltas:
Call
get_face_landmarks(character)to retrieve the current landmark vectors.Build a list of per-landmark Vector deltas.
Call
translate_face_landmarks(character, landmark_indices, deltas).Call
commit_face_state(character).
For an example, see examples/example_sculpt_face.py.
Face Model Coefficients
get_face_model_coefficients and set_face_model_coefficients expose the character's face identity as a vector of floats. This is the lowest-level face sculpt API.
Use it when:
You need to snapshot and restore a face identity around a destructive edit.
You are interpolating or blending between two known characters.
You are driving faces procedurally from data that already produces a coefficient vector.
The basic pattern:
Call
get_face_model_coefficients(character)to retrieve the current vector.Modify, replace, or interpolate the values.
Call
set_face_model_coefficients(character, coefficients).Call
commit_face_state(character)to refresh the preview and serialize the change.
For an example, see examples/example_sculpt_face.py.
Sculpt the Body
Body sculpting uses the parametric body system. A MetaHumanCharacterBodyConstraint drives each slider that appears in the UI. To drive a constraint, activate it and set its target measurement:
Call
get_body_constraints(character)to retrieve the current constraints.For each constraint you want to drive, set
is_active = Trueand assign a value totarget_measurement. Constraints withis_active = Falseare ignored.Call
set_body_constraints(character, constraints).Call
commit_body_state(character).
Constraint names match the labels shown in the UI. For convenience, you can build a lookup keyed by the lowercase, underscore-separated form. For example:
constraints_by_name = {str(c.name).lower().replace(" ", "_"): c for c in subsystem.get_body_constraints(character)} returns a dict you can index as constraints_by_name["height"].
For a full example, see examples/example_sculpt_body.py.
Edit Other Sub-Systems
Teeth, eyelashes, makeup, skin, and eyes follow a common pattern:
Read the relevant sub-property struct off the character. For example,
character.head_model_settings.Mutate the sub-property struct (
head_model_settings.teeth,head_model_settings.eyelashes, and so on).Commit the change with the corresponding function:
commit_head_model_settingsfor sub-systems onhead_model_settings, orcommit_skin_settingsfor skin.
For worked examples, see test_sculpt_teeth and test_sculpt_eyelashes in test_sculpt_character.py.
Assemble a Character
Assembly is the final in-engine stage of the workflow. It builds the runtime assets for one of three pipelines. Pick the pipeline that matches your runtime target:
| Pipeline | Target |
|---|---|
UE Cine | Full cinematic-quality assembly intended for non-interactive rendering. The |
UE Optimized | Real-time pipeline for in-game characters. Quality scales with |
UEFN Export | Pipeline targeting UEFN (Unreal Editor for Fortnite). Quality scales with |
For DCC (Digital Content Creation tool such as Maya, Blender, or ZBrush) output, use the export utilities described in the Export Tools section instead of build_meta_human.
To assemble a character, populate a MetaHumanCharacterEditorBuildParameters struct and call build_meta_human(character, params). The struct fields are:
| Description | |
|---|---|
| One of the values of |
| A value from |
| Optional override for the build output path. |
| Optional override for the common assets folder. |
| Controls whether wardrobe items are validated as part of the build. |
For an example covering the in-engine pipelines, see examples/example_assembly.py.
Export Tools
DCC export and the standalone export utilities live in a separate Blueprint function library, MetaHumanCharacterExportBlueprintLibrary, separate from the in-engine build_meta_human pipelines.
Prerequisites for Export
Before most export operations:
The character must be rigged. See
examples/example_auto_rig.py.The character must have high-resolution textures. See
examples/example_download_textures.py.export_geometryadditionally requires the character to be open for editing.export_posed_dnarequires a priorconform_to_target_meshescall with a matchingtarget_mesh_key.
In Unreal Engine 5.8, Bake Material is supported only on the Cinematic pipeline. On other pipelines, the UI disables the option and shows a warning banner.
Export Functions
The library exposes four export functions:
| Function Name | Description |
|---|---|
| Uses |
| Uses |
| Uses |
| Uses |
For a full walkthrough, see examples/example_export_tools.py.
Migration Notes
The stepwise body conform functions were renamed in Unreal Engine 5.8 when new conform paths were added. Update Unreal Engine 5.7 code as follows:
get_mesh_for_body_conformingis nowget_mesh_for_body_conforming_from_template.get_joints_for_body_conformingis nowget_joints_for_body_conforming_from_template.conform_bodyis nowconform_body_to_target.
The older import_from_body_template function (deprecated in 5.7) and its predecessor conform_body (deprecated in 5.8) remain functional but will be removed in a future release. Use the stepwise template path described in Conform the Body, or conform_to_target_meshes, for new code.
The example_conform_body.py example script still uses import_from_body_template and is out of date.