All plugins

Auto UV

A pure C# general-purpose UV unwrapper: generate an additional, non-overlapping UV set for any mesh — at runtime, in the editor and on procedural meshes.

Unity 6+ Runtime package Editor window Burst · Jobs

Overview

Auto UV generates an additional, non-overlapping UV set (UV0–UV7) for any mesh, usable at runtime, in the editor and on procedural meshes. The most common application is the secondary UV set used for lightmapping (UV2), but the API itself is purpose-independent.

Auto UV: three procedural meshes with colour-block UV islands, and their UV layout panels behind them.
Runtime unwrapping of a sphere, a hard-surface heat sink and a torus, with the generated layout on the panels behind.
  • Any UV channel — writes to UvChannel.Uv (uv0) through UvChannel.Uv8 (uv7); the default is UV2.
  • No overlaps — charts are cut apart and flattened individually, and packing keeps a packMargin between islands.
  • Straighter seams, fewer islands — seam steps are shaved down and small fragments merged into neighbouring islands.
  • Low stretch — normal-cone charting, LSCM flattening and ARAP refinement; round parts such as spheres and capsules are split into regular axial charts.
  • All vertex channels preserved — normals, tangents, vertex colours, UV0–UV7, skin weights, BindShape, BlendShapes and submeshes (line and point submeshes pass through untouched).
  • Runtime ready — no reference to UnityEditor, so it works in players, in the editor and inside frame-spread coroutines.
  • Deterministic — repeated runs on the same input produce bit-identical results.
  • Source mesh untouched — Generate produces a new mesh; use Apply when writing back is intended.
  • Layout preview — UvLayoutRenderer renders any UV channel into a square texture, optionally as flat colour blocks with one colour per island.
Engine
Unity 6+
Channels
UV0–UV7
Default target
UV2 (lightmap)
Dependencies
Burst · Collections

Installation

Copy the whole Assets/AutoUV folder into the target project's Assets/ folder, or import the package. Targets Unity 6000+ and depends only on Unity.Burst, Unity.Collections and Unity.Mathematics.

Assets/AutoUV/
  Runtime/        # runtime assembly AutoUV
  Editor/         # editor window and editor helpers
  Samples/        # ready-to-run sample scene and script
  README.md       # this manual

The runtime assembly has no UnityEditor references, so the same calls work in a player build. The editor window and the auxiliary editor helpers live in the separate AutoUV.Editor assembly.

Quick start

Generate a new mesh

The source mesh is only read, never modified:

var result = UvUnwrapper.Generate(sourceMesh);
if (!result.Succeeded)
{
    Debug.LogError(result.Message);
    return;
}

var mesh = result.Mesh; // new mesh with UV2 written

Provide settings

var settings = new UvUnwrapSettings
{
    targetChannel = UvChannel.Uv2,
    maxNormalAngle = 60f,
    angleError = 1.5f,
    areaError = 1.35f,
    packMargin = 1f / 1024f,
    fineDecomposition = true,
    maxSolverIterations = 512
};

var result = UvUnwrapper.Generate(sourceMesh, settings);

Write in place

// The source mesh must be readable (Read/Write Enabled, or a mesh created at runtime).
UvUnwrapper.Apply(mesh, settings);

Write into a specific target mesh

UvUnwrapper.Generate(sourceMesh, targetMesh, settings);

Coroutine (large meshes without frame stalls)

yield return UvUnwrapper.GenerateCoroutine(
    mesh,
    settings,
    result => Debug.Log($"{result.ChartCount} charts"),
    progress => progressBar = progress);

Progress and cancellation

UvUnwrapper.Trace = message => Debug.Log(message);   // progress messages (stage diagnostics only in development builds)
UvUnwrapper.CancelRequested = () => shouldStop;      // return true to abort generation

These hooks are per play session: they are cleared when a play session starts (this also covers Fast Enter Play Mode), so assign them from Awake, OnEnable, Start or later, not from a static initializer.

The Auto UV runtime API: settings, Generate, and assigning the result to a renderer.
One API for the editor, runtime scripts and frame-spread coroutines.

Result reference

Every call returns a UvUnwrapResult:

MemberDescription
Succeeded / MessageWhether the run succeeded; the failure reason.
MeshThe generated mesh (null on failure).
ChartCountNumber of UV islands.
SourceVertexCount / VertexCount / TriangleCountSource vertices, output vertices after splitting, and triangles.
UvCoverageFraction of the 0–1 square covered by UVs.
ChannelUV channel that was actually written.
DurationMillisecondsTotal duration.
ProfilePer-stage timings; only non-null in development builds (AUTO_UV_DEV).

Settings reference

FieldDefaultDescription
targetChannel Uv2 Which channel to write. Enum names follow "which UV set", values are the API channel index: Uv → 0 (mesh.uv), Uv2 → 1 (mesh.uv2) … Uv8 → 7 (mesh.uv7).
hardAngle 88 Angle threshold for smooth adjacency: adjacent faces whose normals differ by more than this are not connected, so charts do not grow across hard edges.
maxNormalAngle 60 Maximum normal spread per chart; lower values reduce stretch and increase the island count.
angleError 1.5 Angle-error budget (p95 triangle anisotropy); charts above it are split.
areaError 1.35 Area-error budget (p95 deviation of the UV/3D area ratio).
fineDecomposition true Build small charts first and merge them under the quality gate; false builds coarse charts and splits them down.
packMargin 1/1024 Spacing between islands in 0–1 space.
maxSolverIterations 512 LSCM iteration cap per chart.
splitOnUvSeams false Split charts along existing UV0 seams; off by default to avoid chopping limbs into strips.

Settings are cloned and clamped to their valid ranges when a generation starts; the instance you pass in is never modified.

Editor window

Open the window with Tools ▸ Auto UV ▸ Unwrapper, select mesh assets, GameObjects or prefabs, then generate UVs.

  • The preview follows the selection and the target channel. Scroll to zoom, drag to pan, double-click to reset the view. The dark preview area follows the window's aspect ratio; the UV square is fitted to the shorter side and always stays square. Zooming and panning are immediate and crisp. Fully stacked UV footprints are reported below the preview.
  • Color Block Texture / Triangle Mesh — show the preview as flat colours per UV island and/or triangle edges. Colour Block off + Triangle Mesh on is a lines-only wireframe with no fill; both on shows the fills with the triangle edges on top.
  • Preview (next to the Unwrap button, off by default) — previews the layout generated from the current settings instead of the mesh's stored UVs.
  • Update Source Mesh — writes the generated UVs into the selected meshes. With it off, the results are saved as mesh assets or prefabs in a chosen folder and revealed in the Project window; scene objects are copied, so the scene is not modified. A skinned renderer is saved together with its skeleton.
  • Export Color Block Texture — also creates a colour-block texture and applies it to the generated model: a prefab embeds it as a sub-asset, a mesh asset gets a separate texture asset.
The Auto UV runtime sample scene with live unwrap statistics, controls and UV layout panels.
The included runtime sample reports charts, vertices, coverage and unwrap time per mesh.

Preview the UV layout

var texture = UvLayoutRenderer.Render(mesh, UvChannel.Uv2, 1024);

RenderPixels returns a Color32[] and can run on a worker thread; CreateTexture uploads it on the main thread. Pass colorBlocks: true for per-island colours and drawTriangles: false to hide the edges; RenderColorBlockTexture builds the texture applied to a model.

Three readable UV layouts: a smooth sphere, a hard-surface heat sink and a torus, each with colour-coded islands and chart counts.
Colour blocks plus a high-contrast wireframe, rendered for any UV channel.

Sample

Samples/Scenes/AutoUV Demo.unity unwraps three procedural meshes at runtime and shows the generated colour blocks on the models and the UV layout on panels behind them. Open the scene and press Play. The sample component also runs in edit mode, so the finished result appears without entering play mode; in play mode the on-screen HUD regenerates the UVs with different presets and can switch the target channel.

The Auto UV sample scene: a sphere, a heat sink and a torus on pedestals with their UV layout panels.
Everything in the demo scene is created by the sample script at load time.

Notes

  • Read-only meshes — Generate only reads the source mesh and never modifies it. In the editor it normally works even when the asset's Read/Write Enabled is off; the descriptive exception is only thrown when the CPU data really has been stripped, typically in a player build.
  • In-place writes (Apply) require Read/Write, otherwise they throw an exception that points at Generate instead.
  • Imported model meshes (.fbx, .obj, …) cannot be updated in place: the model importer regenerates them. Disable Update Source Mesh to generate a copy instead.
  • Non-triangle submeshes (lines, points) are preserved verbatim; their vertices get a UV of 0.
  • Fast Enter Play Mode — the Trace and CancelRequested hooks are reset when a play session starts. The other runtime statics are immutable caches, primitive scratch buffers, or counters that are reset at the start of every pass, so keeping them across play sessions is intentional and safe.

Development switch

Detailed per-stage profiling and the development tools are not shipped with release builds and are controlled by the AUTO_UV_DEV define (undefined by default).

FeatureUndefined (release default)AUTO_UV_DEV defined
Stage timings (result.Profile)No-op; Profile is nullAccumulated per stage
Diagnostic(...) messagesCalls and their strings are compiled outEmitted through UvUnwrapper.Trace
Report(...) progress messagesRetainedRetained
Tools ▸ Auto UV ▸ Run Benchmark and Generate Verification SamplesNot compiledAvailable