Maya 2027 | Python 3
PySide6 | Unreal Engine
Maya Vertex Animation Texture Export Tool
This tool is a modified version of the Maya Vertex Animation Tools shared in the Epic Developer Community forum. The original Maya tool is a Python conversion of Jonathan Lindquist's Vertex Animation Tools MaxScript.
My role: Updated an existing open-source Maya VAT tool to run in Maya 2027 with Python 3 and PySide6, and fixed UV handling issues that broke bakes on production meshes.

Output Example


Overview
Maya Vertex Animation Texture Export Tool is a Maya exporter that bakes animated mesh deformation into Vertex Animation Texture (VAT) data for playback in Unreal Engine.
This tool samples an animated mesh over a frame range and converts per-vertex motion into textures that a VAT material in Unreal Engine can read. This lets complex deformation play back on a static mesh through World Position Offset, without skeletal animation.
Pipeline
Animated mesh in Maya → Frame sampling → Offset / normal textures + anim_map UV set → VAT material in Unreal Engine
VertexAnimationTools.py — Main tool and UI
- Samples the animated mesh at each frame and creates mesh snapshots
- Generates the anim_map UV set, which maps each vertex to its own column in the texture
- Stores per-vertex position offsets and normals
- Exports the result as textures (width = vertex count, height = frame count)
EXR_Dumper.py — Writes vertex offset data to an uncompressed 16-bit half-float RGB EXR file.
Problems & Solutions
1. Qt version mismatch
Problem: The original tool imported PySide2, which is not available in Maya 2027.
Solution: Switched the import to PySide6 and removed the call to QImage.byteCount(), which no longer exists in Qt 6. Its return value was not used, so removing it had no side effects.
2. Bake failure on UV seams and missing UVs
Problem: The UV packing code assumed each vertex converts to exactly one UV component. This caused an IndexError on vertices without UVs, and ignored UV seams, where one vertex is split into several UV components.
Why it matters: At a seam, every UV belonging to the same vertex must point to the same texture column. Otherwise, the split UVs read different animation data and the mesh tears apart during playback.
Solution:
- Process all UV components connected to each vertex, so seams stay intact
- Skip vertices without UVs and show a Maya warning, instead of stopping the entire bake
3. Python 2 binary output in Python 3
Problem: EXR_Dumper.py relied on Python 2 behavior, where str doubled as binary data. In Python 3 this raised a TypeError when joining text and bytes.
Solution: Rewrote the binary output to use bytes and byte literals, b''.join(), and ASCII-encoded header values, and replaced xrange() with range().
Unreal Engine Setup
The exported textures are imported with sRGB, compression, and mipmaps disabled so vertex data is read without distortion. The VAT material samples them using the anim_map UV set and drives World Position Offset per frame.
Limitations & Next Steps
- Texture width scales with vertex count, so high-poly meshes can exceed practical texture size limits. Wrapping vertices across multiple rows would remove this limit.
- Vertices without UVs are skipped and will not animate correctly. Automatically generating a fallback UV would make the tool more robust.