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 | |
|---|---|
| Unity | 2021.3 LTS |
| Build targets | iOS, Android, Windows, macOS |
Installation
Unity Package Manager (recommended)
In Unity: Window → Package Manager → + → Add package from git URL:
https://github.com/appspacer/appspacer-unity.gitOr 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
| Property | Type | Default | Description |
|---|---|---|---|
apiKey | string | Required | Your AppSpacer API key |
appVersion | string | Required | App version (e.g. Application.version) |
updateStrategy | UpdateStrategy | OnInit | OnInit, Background, or Manual |
crashReportingEnabled | bool | true | Capture Unity LogType.Exception |
debugLogging | bool | false | Verbose 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.jsonThe bundle-name value must match the name you pass to AppSpacer.GetBundle("ui_assets").
API Reference
| Method | Description |
|---|---|
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.SessionId | Current 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. Reportinstalled/failedback toreport-statusso 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/.