# stream-unity

`/stream-unity` builds, integrates, and answers how-to questions for Stream Chat and Stream Video in Unity Engine games and apps: C# and `MonoBehaviour`, the Chat `.unitypackage` and the Video UPM package, `StreamChatClient` / `StreamVideoClient` wiring, channels and messages, calls and participant tracks, IL2CPP, and the per-platform player settings that decide whether a build works on device.

<Admonition type="note">

**Chat and Video only, and they are two separate SDKs.** There is no Stream Feeds SDK for Unity. The skill says so up front and offers the server API instead of inventing one. Chat (v5.x, stable) and Video (0.11.0, pre-1.0) share only the API key: different repos, install mechanisms, assemblies, and `AuthCredentials` types, so "add chat to my call app" is two integrations. And neither SDK ships UI components. Both ship a sample project to read, so every channel row, message bubble, and participant tile is code the skill writes.

</Admonition>

<Admonition type="tip">

The router installs and dispatches to `/stream-unity` automatically when it detects a Unity signal (`unity`, `unity 6`, `monobehaviour`, `.unitypackage`, `asmdef`, `il2cpp`, `ugui`, `StreamChatClient`, `StreamVideoClient`, `IStreamCall`), or you can invoke it directly.

</Admonition>

## What it builds

Before writing any code, three gates run:

1. **Product.** Chat and Video are supported; both means two installs, two clients, two connect calls. Activity feeds get an immediate no plus the server-API alternative, and moderation review is pointed at the Dashboard.
2. **Unity version and build target**, probed from `ProjectSettings/ProjectVersion.txt` rather than asked. Video needs Unity 2020.3+; Chat goes back to 2019.4. WebGL is a hard stop for Video (Unity's WebRTC does not support it) but works for Chat; Android Video is ARM64 only; UWP is Chat only. Unity 6 pins Chat to v5.4.0 or newer: earlier versions crash IL2CPP builds.
3. **Feature support**: the skill says no in the plan, not in a compile error. Chat has no guest/anonymous connect, user blocking, drafts, or channel archiving; Video cannot publish a screen share (receive only), surfaces no incoming-call/ringing event, and has no public push device registration: devices register from your backend.

With the gates passed, it installs the product(s) asked for (Chat as a `.unitypackage` from GitHub Releases, Video as a tag-pinned UPM git dependency in `Packages/manifest.json`), collects credentials (API key and user token minted via the `getstream` CLI, or pasted), wires each client exactly once on a persistent `DontDestroyOnLoad` manager with correct teardown, and builds the UI itself against the stateful models, matching the project's UGUI or UI Toolkit choice. Docs lookups route through a per-page coverage map to the live `.md` docs pages, falling back to the SDK source in the project for the many shipped APIs the docs never covered.

## Example prompts

```bash
/stream-unity add in-game chat to my Unity 6 project
/stream-unity put a video call with participant tiles in my game
/stream-unity how do I query channels?
/stream-unity why is the remote participant's tile black on Android?
```

## What it knows

- The docs-coverage caveat, which differs per product: Chat pages mix two SDKs behind identical-looking C# fences: only `label="Unity"` blocks are client code, while `label="C#"` is the .NET server SDK that needs the API secret and must never reach game code. The Video tree is trustworthy but small (22 pages), so undocumented-but-shipped APIs (`GoLiveAsync`, `StartHLS`, recording control) are read from `IStreamCall` and cited as such
- `CreateDefaultClient()` spawns a hidden `DontDestroyOnLoad` runner, so a client created in a reloadable scene means a duplicate WebSocket per reload. Create once on a persistent manager, and `Dispose()` does not disconnect the user: `DisconnectUserAsync()` first
- Incoming Video media must be bound by hand (`SetRenderTarget` for video, `SetAudioSourceTarget` for audio, from `participant.TrackAdded`), or the call connects perfectly and shows a black, silent tile with no error; incoming video is also capped at 5 participants by default
- The Chat SDK is stateful: one `QueryChannelsAsync`, then the WebSocket keeps `Messages`/`Members` fresh. Never poll, never call Stream APIs per frame
- Dependency collisions: Chat vendors Newtonsoft.Json (delete one copy if the project already has it), and Video embeds a forked WebRTC package. Adding `com.unity.webrtc` alongside it breaks the build. Scripts under their own `.asmdef` must reference `StreamChat.Core` / `StreamVideo.Core` or nothing resolves
- IL2CPP stripping removes the SDKs' reflection-deserialized types unless each `link.xml` survives in `Assets/`: the failure is player-only, at runtime, with no editor warning
- The load-bearing player settings: Android Video needs IL2CPP + ARM64 + API 23 + Internet Access "Require"; iOS needs camera/microphone usage descriptions (set after switching the target; the fields do not exist before), Bitcode off, and DSP Buffer Size at Best Latency

The pack's files live at [`skills/stream-unity/`](https://github.com/GetStream/agent-skills/tree/main/skills/stream-unity).


---

This page was last updated at 2026-08-22T17:29:30.109Z.

For the most recent version of this documentation, visit [https://getstream.io/agent-skills/docs/skills/stream-unity/](https://getstream.io/agent-skills/docs/skills/stream-unity/).