Repository navigation
Highlights
- Profiling in one call.
profile capture start --frames N --waitwaits for the capture and returns the summary.profile capture stopon a capture that already finished returns its result instead of an error, and a 0-frame capture reportsPROFILE_EMPTY. - Find the allocating script.
gcByScriptattributesGC.Allocbytes to the nearest script marker, andgcTopno longer fills up with player-loop containers and engine phase markers. - Per-marker stats.
profile stats --marker ThreatField.Updatereports min/median/p95/max ms, calls per frame, and GC bytes per frame over N frames. Short marker names now resolve everywhere. - Smoother commands.
scene open,scene inspect, andasset reimport/mkdir/deletetake the path as a positional argument;execute --codehoists leadingusingdirectives;unity-cli --versionprints the package version (0.6.1+<sha>). - In our own Play Mode profiling benchmark scenario (GC allocation, CPU time, frame time, and texture count checks), an agent using ucb 0.6.1 finished in about 46% less time and at about 28% lower cost than with ucb 0.6.0.
executelatency is unchanged.
Assets
com.yhc509.unity-cli-bridge-0.6.1.unitypackage: Unity package (Assets > Import Package > Custom Package…)unity-cli-osx-arm64.tar.gz: CLI for macOS Apple Siliconunity-cli-win-x64.zip: CLI for Windows x64
Or add the package by Git URL: https://github.com/yhc509/unity-cli-bridge.git?path=/unity-package/com.yhc509.unity-cli-bridge#v0.6.1
[0.6.1] - 2026-10-26
Added
profile analyze <captureId>with no mode returns the capture summary.hotspots,gcTop, andspikesare undersummary.profile analyze --markeraccepts a short script name. An exact marker name still wins. Otherwise the name is matched after anAssembly.dll!Namespace::prefix, a trailing() [Invoke], and parentheses are removed, soThreatField.UpdateandThreatField.Update()resolveAssembly-CSharp.dll!::ThreatField.Update() [Invoke]. One match is used and the response includesresolvedMarker. Several matches returnPROFILE_MARKER_AMBIGUOUSwith the candidate names. A name that matches nothing includes up to five similar marker names.unity-cli versionandunity-cli --versionprint this CLI's version. It is the Unity package version plus the git revision (0.6.1+<sha>), taken from the packageversionat build time.- Leading
usingdirectives inexecute --codeare hoisted above the wrapper, including a one-line snippet such asusing UnityEngine; return Application.unityVersion;.--filealready hoisted usings that were on their own lines. The compile cache key is still the wrapped source. profile capture start --waitwaits for the capture to finish and returnscaptureId,capturedFrames, andsummary(theprofile analyzesummary) in one call. It needs--framesor--duration.--timeout <seconds>defaults to 60 s plus 0.25 s per frame (or the duration). On timeout it fails withPROFILE_WAIT_TIMEOUT, which names thecaptureIdand the frames captured so far. The capture keeps running.profile stats --marker <name>(repeatable, up to 10) measures named profiler markers over--framesframes: ms min/median/p95/max, calls per frame, and GC bytes per frame. Names resolve the same way asprofile analyze --marker, soThreatField.Updateworks. Script markers are recorded only while the profiler runs (checked on Unity 2021.3 and 6000.3), so the command turns the profiler on for the measurement and restores it after. Each result'spathsays whether the time came fromProfilerRecorder(recorder) or from the profiler frame hierarchy (capture). GC bytes always come from the frame hierarchy.- The capture summary and
profile analyze --gcaddgcByScript:GC.Allocbytes attributed to the nearest script marker above each allocation, withbytesPerFrame, plusgcUnattributedBytesfor allocations with no script marker above them. - The profiling guide describes how to compare memory and object counts over time in Play Mode without a fixed sleep. Sample with
profile memoryandprofile memory top(for example--type Texture2D), advance frames withprofile capture start --frames <n> --wait, sample again, thenprofile memory comparethe two reports.
Changed
- Default and compact text output shows identical lines that repeat back-to-back in an
executelog once, asline (×N).--jsonkeeps every line. - Default and compact text output of a compile failure keeps the diagnostic lines and drops the
/define:list and reference list.--jsonstill includes the full message. - Compact
statusomitspipeNameanddomainId.--jsonand the default text output still include them. execute --helpdescribes the default Roslyn host (C# 9). mcs is used only whenUCB_EXECUTE_COMPILER=codedom.profile capture stopafter the capture already finished on its own (--framesor--durationreached, the 600 s cap, or Play Mode ended) returns that capture'scaptureId,capturedFrames, andsummarywithnotice: PROFILE_ALREADY_COMPLETEDinstead ofPROFILE_NOT_RUNNING.PROFILE_NOT_RUNNINGremains for an Editor session with no running and no finished capture.- A capture that records 0 frames is no longer reported as
Completed. Its status isEmpty, andprofile capture stop,stop --wait, andstart --waitfail withPROFILE_EMPTY(retryable), thecaptureId, and a hint to retry with--frames <n> --wait. gcTopin the capture summary,profile analyze, andprofile analyze --gcleaves out the player-loop containers (PlayerLoop,UpdateScene,BehaviourUpdate,Update.ScriptRunBehaviourUpdate, and the LateUpdate and FixedUpdate equivalents) andGC.Allocitself. Their GC column is the total of everything below them, so they used to fill the list.- Capture sidecars are
schemaVersion2, which addsgcByScriptandgcUnattributedBytes. Version 1 sidecars still load. TheirgcByScriptis empty, andnotessays the capture was recorded before GC attribution. scene openaccepts the scene path as a positional argument (scene open Assets/Scenes/Foo.unity) as well as--path.scene inspect,asset reimport,asset mkdir, andasset deletedo the same: each takes one asset path, and that path may be positional or--path. There is noscene saveorscene close. If two different paths are given, the command fails withCLI_USAGEand names both paths. The same path given both ways is accepted.asset deletestill requires--force.
Fixed
profile capture startstill clamps--framesto the profiler buffer (300 frames on Unity 2021.3, 2000 on Unity 6). A clamped capture records up to that buffer and can come back slightly short, because the ring buffer rotates. The finished summary reportscapturedFrames(the actual count) next toframeClamp(requested,clamped,bufferLimit).warningandframeClampare included only when the request was clamped; unclamped start,--wait, andstopresponses omit both.requestedFramesis the clamped cap. A--waittimeout check uses--duration, or a--framescount inside the buffer.gcTopandgcByScriptleave out engine end-of-frame and PlayerLoop phase markers such asPlayerEndOfFrame,PostLateUpdate, andPostLateUpdate.*. Allocation under those markers is attributed to the nearest script marker above them, or counted as unattributed. Script markers such asThreatField.Update()stay ranked.profile capture stop --waitreturns the same shape asstopon a capture that already finished:captureId,status,capturedFrames, andsummary.notice: PROFILE_ALREADY_COMPLETEDis set only when the capture had already finished on its own.