How I Speed Up My Asset Store Publishing Process
Learn how to automate Unity asset packaging and export in seconds, skipping the editor.
By Tim Uhlott|Last updated: January 10, 2026|8 minutes read
unityoptimizationcli

If you are a Unity asset developer, this is a must-read for you.
If you’ve ever published an asset to the Unity Asset Store, you probably know that the last step, packaging your work, can be surprisingly slow. For me, this step became such a bottleneck that I decided to completely rethink it. The result was a faster, automated way to create Unity packages without even opening the editor.
In this article, I explain the problem, how my workflow changed, and how Unity packages work behind the scenes.
With Unity, even a small change can cost multiple minutes just to create a package. With the automated approach, the same task takes about 10 seconds.
There’s no editor startup, no script compilation, and no UI interaction. Because everything is automated, the process is reliable and easy to integrate into build servers or CI pipelines. Once I switched to this workflow, packaging stopped being something I had to plan around, it just happens.
The Problem: Waiting on Unity
The traditional way to create a.unitypackage is through the Unity Editor and the Asset Store Publisher tools. While this works, it comes with a lot of waiting.
Unity can take minutes just to start and prepare a project. After that, it refreshes assets, recompiles scripts, and finally lets you open the export window. Only then can you select your assets and pack them.
If you’re releasing frequent updates or maintaining multiple assets, this waiting time adds up fast. I realized I was spending more time waiting for Unity than actually improving my assets.
A Faster Approach: Automated Packaging
Instead of relying on the Unity Editor, I analyzed how Unity packages are built and how this process could be automated. Based on that, I built a tool that packages assets without launching Unity at all. It runs from the command line and can be fully automated. Breaking the process into steps makes the difference very clear:| Process | Start-up | Compile | Pack | Total |
|---|---|---|---|---|
| Unity Editor | 3 minutes | 1 minute | 1 minute | 5 minutes |
| Automated | – | – | 10 seconds | 10 seconds |
What Is a .unitypackage, Really?
A.unitypackage file is, at its core, a GZipped tarball (.tar.gz): a compressed archive with a very specific structure.
When you unpack a .unitypackage, you won’t see folders like Assets/Scripts/Player.cs. Instead, you’ll find a list of folders named after Unity GUIDs, where each GUID represents one asset.
Each folder contains:root/ ├── [GUID_1]/ │ ├── asset │ ├── asset.meta │ └── pathname ├── [GUID_2]/ │ ├── asset │ ├── asset.meta │ └── pathname └── ...
asset: the raw binary or text data of the assetasset.meta: the metadata Unity uses for import settings and referencespathname: a text file that tells Unity where the asset should be placed when imported
The Packing Process: Finding the Right Assets
Packaging is not just about copying files. Unity assets are heavily interconnected, and missing a dependency can easily break a package.Asset Discovery
The process starts by discovering which assets should be included, usually from a folder or pattern likeAssets/MyTool. Each asset is checked for a .meta file, because Unity relies on meta files to assign and track GUIDs.
These GUIDs are defined at the top of the meta file and look like this:
These GUIDs are collected to build the folder structure and are later matched during dependency analysis against other assets.guid: a1b2c3d4e5f6...
Dependency Analysis
Many Unity assets, such as prefabs, materials, and scenes, are stored as text files using a YAML format. Inside these files, references appear as fileID and GUID pairs, for example:To find these efficiently, I rely on regex:fileID: 123456, guid: a1b2c3d4e5f6...
new Regex(@"fileID: ([\-0-9]+), guid: ([a-z0-9]+)");
Small C# tip: use RegexOptions.Compiled.
This specifies that the regular expression is compiled to MSIL code instead of being interpreted. Compiled regular expressions maximize runtime performance at the expense of initialization time. When used frequently, they are extremely fast.
So, compiled regular expressions are used to detect these references. Every referenced GUID is then matched against GUIDs defined in .meta files, which look like this:
guid: a1b2c3d4e5f6...
Packaging
After the analysis step, you can build a dependency graph. Any asset that is referenced, directly or indirectly, is automatically included in the package. This ensures that prefabs keep their materials, scripts keep their dependencies, and the package works out of the box. The actual packing step is then simple: iterate over all discovered GUIDs, create a directory for each one, add the requiredasset, asset.meta, and pathname files, then gzip everything, and you’re done.
root/ ├── [GUID_1]/ │ ├── asset │ ├── asset.meta │ └── pathname ├── [GUID_2]/ │ ├── asset │ ├── asset.meta │ └── pathname └── ...
How Much Time I Saved
I reduced my publishing process more than 90%. I build different assets, mostly cybersecurity solutions. For example, my Obfuscator is released for Unity 2021, 2023, and 6000, three versions. For each version, there are three tiers: Free, Pro, and Source. That’s 9 uploads total. Using the Unity Editor, each package takes about 5 minutes, resulting in roughly 45 minutes total. Using the automated process I described, I reduced the entire workflow to around 30 seconds. I created a small PowerShell script for this process:# Export-UnityPackages.ps1 param ( [Parameter(Mandatory = $true)] [string]$OutputDirectory, [Parameter(Mandatory = $true)] [string[]]$Versions ) # Ensure output directory exists if (!(Test-Path $OutputDirectory)) { New-Item -ItemType Directory -Path $OutputDirectory | Out-Null } foreach ($version in $Versions) { $sourcePath = "..\$version" $outputPackage = Join-Path $OutputDirectory "$version.unitypackage" Write-Host "Exporting Unity package for version $version..." dotnet UnityPackageExporter.dll ` $sourcePath ` $outputPackage ` --assets "Assets/MyTool/**.*" ` --skip-dependency-check }
This produces:.\Export-UnityPackages.ps1 -OutputDirectory "..\packed" -Versions "1.0.0","1.1.0","2.0.0"
packed/ ├─ 1.0.0.unitypackage ├─ 1.1.0.unitypackage └─ 2.0.0.unitypackage