Skip to Content

Unity SDK

com.appspacer.unity — AssetBundle OTA updates and crash reporting for Unity games and apps.

Update model: AppSpacer for Unity downloads and caches Unity AssetBundles over the air. Your game loads the latest bundle via AppSpacer.GetBundle() and Unity instantiates assets from it normally — prefabs, textures, audio, scriptable objects, and more.


Requirements

Minimum
Unity2021.3 LTS
Build targetsiOS, Android, Windows, macOS

Installation

In Unity: Window → Package Manager → + → Add package from git URL:

https://github.com/appspacer/appspacer-unity.git

Or add to Packages/manifest.json:

{ "dependencies": { "com.appspacer.unity": "https://github.com/appspacer/appspacer-unity.git" } }

Editor Setup

After installing, open Window → AppSpacer → Setup to enter your API key and save a config asset.


Initialization

Call AppSpacer.Initialize() from your bootstrapper MonoBehaviour:

using AppSpacer; public class GameBootstrap : MonoBehaviour { void Awake() { AppSpacer.AppSpacer.Initialize(new AppSpacerConfig { apiKey = "your_api_key", appVersion = Application.version, crashReportingEnabled = true, updateStrategy = UpdateStrategy.OnInit, }); } }

Config Options

PropertyTypeDefaultDescription
apiKeystringRequiredYour AppSpacer API key
appVersionstringRequiredApp version (e.g. Application.version)
updateStrategyUpdateStrategyOnInitOnInit, Background, or Manual
crashReportingEnabledbooltrueCapture Unity LogType.Exception
debugLoggingboolfalseVerbose Debug.Log output

Loading OTA AssetBundles

using AppSpacer; using UnityEngine; public class UIManager : MonoBehaviour { IEnumerator Start() { // Wait for SDK to check for updates (if using OnInit strategy) yield return new WaitForSeconds(1f); // Load from OTA cache (falls back to null if not downloaded yet) AssetBundle bundle = AppSpacer.AppSpacer.GetBundle("ui_assets"); if (bundle != null) { var prefab = bundle.LoadAsset<GameObject>("MainMenuPanel"); Instantiate(prefab); } else { // Fall back to Resources or Addressables var prefab = Resources.Load<GameObject>("MainMenuPanel"); Instantiate(prefab); } } }

Manual Update Check

IEnumerator CheckForUpdates() { yield return AppSpacer.AppSpacer.CheckForUpdates(result => { switch (result.Status) { case OTAUpdateStatus.Updated: Debug.Log($"Updated {result.UpdatedCount} bundle(s): {string.Join(", ", result.UpdatedBundles)}"); break; case OTAUpdateStatus.UpToDate: Debug.Log("Already up to date"); break; case OTAUpdateStatus.NoNetwork: Debug.LogWarning("No network"); break; case OTAUpdateStatus.Failed: Debug.LogError($"Update failed: {result.Error}"); break; } }); }

Crash Reporting

Unity LogType.Exception and LogType.Error messages are automatically captured via Application.logMessageReceived.

// Report a handled exception try { DoRiskyThing(); } catch (System.Exception ex) { AppSpacer.AppSpacer.ReportError(ex); } // Breadcrumbs AppSpacer.AppSpacer.AddBreadcrumb("Level loaded", "gameplay"); AppSpacer.AppSpacer.AddBreadcrumb("Shop opened", "ui");

Preparing AssetBundles

Build your AssetBundles normally in Unity, then push them via the CLI:

# Push a single AssetBundle file appspacer push -a my-game -d Production -p unity --bundle ui_assets.bundle --bundle-name ui_assets # Push a manifest (multiple bundles) appspacer push -a my-game -d Production -p unity --manifest bundle-manifest.json

The bundle-name value must match the name you pass to AppSpacer.GetBundle("ui_assets").


API Reference

MethodDescription
AppSpacer.Initialize(config)Initialize — call once, auto-creates a DontDestroyOnLoad GameObject
AppSpacer.CheckForUpdates(callback)Coroutine — check and download new bundles
AppSpacer.GetBundle(name)Load a cached AssetBundle by name
AppSpacer.ReportError(ex, onComplete)Report a handled exception
AppSpacer.AddBreadcrumb(message, category)Add crash context breadcrumb
AppSpacer.ClearBreadcrumbs()Clear breadcrumb trail
AppSpacer.SessionIdCurrent session identifier

Backend Integration

GET /api/sdk/unity/manifest Headers: x-api-key: <your_api_key> Query: app_version, current_bundle_id, install_id POST /api/sdk/unity/report-status Body: { release_id, device_id, app_version, status, error_message }

Send install_id (a stable per-device ID) on every manifest call — it is required for staged-rollout targeting and monthly active-user metering. Report installed/failed back to report-status so egress is billed once per device and failed installs can trigger auto-rollback.

The manifest response lists bundles (not individual files). Each entry has name, url, checksum, and size. The SDK downloads, verifies SHA-256, and writes each bundle to Application.persistentDataPath/appspacer/.

Last updated on