Unity Batch (command line)
MeliteUnityBatch, the Headless Build Node
- log
Most ComfyUI nodes end in pixels. This one ends in a process. MeliteUnityBatch - menu name Unity Batch (command line) - writes nothing to your output folder. It shells your installed Unity editor headlessly, runs one static C# method inside one of your Unity projects, and hands back the run log as a string. That's the whole node.
Why bother? Because the last mile of a lot of real work isn't an image. You generate textures or tiles in the graph, then somebody has to import them into a game project, re-bake a lightmap, rebuild an AssetBundle, run a test pass - normally a human tabbing over to the editor, or a CI job on another box. This makes it one more step in the graph. No key, no credits, no network either: the API family phones a provider, this reaches a binary on your own disk. Plumbing with a side effect, as the node-plumbing doc would file it.
How it actually works
Read the source and it's almost anticlimactic. proxy.py resolves a Unity binary: MELITE_UNITY_BIN, then UNITY_BIN (an explicit path wins), else a PATH lookup for a binary named literally unity. No real file either way and you get a loud RuntimeError before any run starts.
Then it runs an argv list: unity -batchmode -quit -projectPath <project> -executeMethod <Class.Method>, plus -openScene <scene> if you set one, plus your extra_args. It's a list, not a shell string, so paths with spaces survive intact. And subprocess.run is synchronous - while Unity works, ComfyUI waits and the queue stalls, which is why timeout is a first-class widget.
On a non-zero exit you get a RuntimeError carrying Unity's stderr tail (last 2000 characters), which is where you'll actually diagnose things. On success you get stdout and nothing else.
The inputs that matter, and the one output
project_path is required: the absolute project directory. The tooltip says "contains Assets/", and that's the test - no Assets/ means you're at the wrong level of the tree. execute_method is required too: ClassName.MethodName, a static method in the project. Note who does the work: this pack ships zero C#. You write that method; the node only calls it.
Optional: scene opens a scene first (-openScene; empty uses the project default). extra_args is a JSON list of extra CLI args - ["-nographics", "-logFile", "/tmp/unity.log"] - and typing -nographics bare is the classic mistake that gets you a JSONDecodeError. timeout is an int, 60–3600 in steps of 60, default 600.
The single output is log, a STRING. Beginner trap: this isn't an output node, and ComfyUI executes by walking backward from output nodes. Drop it on the canvas and queue and nothing happens. Wire log into something terminal - a text preview or save-text node - and it joins the execution path. Related: the node declares no IS_CHANGED, so when a downstream output node's inputs haven't changed, the cache skips the run entirely. Re-queued and Unity didn't fire? Nudge a widget.
Installing it
The best thing about this pack is the install: requirements.txt is deliberately empty, pyproject.toml lists no dependencies, and only stdlib gets imported. In this ecosystem, that's a genuine relief.
In ComfyUI Manager, search Melite Unity Nodes. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/JayDataEngineer/melite-unity-nodes
# then restart ComfyUI however you launch it
Unity itself is on you. The pack's law, in the README and enforced in code, is that it never installs Unity - no downloads, no Hub automation, no bundled binary. Point it at a real one, in the server's own environment:
export UNITY_BIN="$HOME/Unity/Hub/Editor/6000.0.30f1/Editor/Unity"
# before launching ComfyUI, then restart it
Where people get burned
The env var has to be visible to the ComfyUI server process - the code reads os.environ at run time, so exporting it in another terminal changes nothing; Docker and systemd launches need it in the unit or compose file. The PATH fallback also looks for lowercase unity, while the binary is Unity on Linux and lives inside Unity.app/Contents/MacOS/Unity on macOS, where which is case-sensitive. Just set MELITE_UNITY_BIN and stop thinking about it - and if it points at something that isn't a file, you get a hard error rather than a fall back to PATH, by design.
Headless Unity needs an activated license on that machine, and a license failure looks the same from here as a project compile failure: non-zero exit, cause in the stderr tail the node hands you.
The timeout kills the process, and a killed editor is known for leaving Temp/UnityLockfile behind, so the next run may complain the project is already open. Builds are slow; 600 seconds is optimistic for anything real.
One more: a shared workflow JSON carries project_path and execute_method - a command line someone hands you, run on your machine. ComfyUI has no sandbox and never has (the LLMVISION incident). And the honest caveat: this pack is days old with no community footprint, so there are no battle reports, only a short and readable source. If you've got Unity and a project on the ComfyUI box, it's a tidy bridge. If not, this isn't a reason to install a game engine.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| project_path | STRING | Absolute path to the Unity project directory (contains Assets/). | |
| execute_method | STRING | Static method to run (ClassName.MethodName in the project). | |
| sceneopt | STRING | Scene to open first (-openScene; empty = the project's default). | |
| extra_argsopt | STRING | [] | JSON list of extra CLI args appended after the method (e.g. -nographics). |
| timeoutopt | INT | 60060–3600 | Seconds before the headless run is killed. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| log | STRING | — |