Unity Room Operations
Build a Unity room scene with com.mediasfu.unity 0.1.0-preview.2. The
MediaSfuClient gives your scene room state, participant events, media
connection, local and remote track operations, screen sharing, participant
leave, and a host end-room request.
Before you start
- Use Unity 2022.3 and install both
com.mediasfu.unityand its requiredcom.mediasfu.mediasoup-client-unitypackage. - Attach the native WebRTC device and your scene's local/remote media bridges before you try to capture or render media.
- Configure microphone, camera, screen-capture, and platform privacy settings for every desktop, mobile, or console target you ship.
- Decide who can create a room, join, produce media, and end the session in your authenticated application backend.
Keep room authority off the game client
Your distributed Unity player is not a safe place for a reusable MediaSFU API credential. Send the player's room intent to your authenticated application backend instead:
public interface IAuthorizedRoomGateway
{
Task<AuthorizedRoomHandoff> CreateAsync(RoomIntent intent, CancellationToken cancellationToken);
Task<AuthorizedRoomHandoff> JoinAsync(RoomIntent intent, CancellationToken cancellationToken);
}
The current preview package's direct MediaSfuClient startup contract uses
MediaSfuClientOptions.Credentials. It does not publish a backend-authorized
handoff or adapter constructor. Therefore this guide does not give a direct
client create/join setup snippet, and you must not place credentials in a
scene, prefab, ScriptableObject, player preference, build setting, or source
file. A secure distributed-game create/join integration needs a package-level
backend-authorized handoff contract before it can be documented here.
Your backend remains responsible for player authentication, role policy, capacity, rate limits, room creation, and revoking any unused authority.
Work with the active room
After your approved room startup establishes an active MediaSfuClient, attach
room-state events once and remove them when the scene closes.
client.ParticipantJoined += OnParticipantJoined;
client.ParticipantLeft += OnParticipantLeft;
var participants = client.CurrentRoom?.Participants;
void OnParticipantJoined(MediaSfuParticipantEvent change)
{
RefreshParticipantList();
}
void OnParticipantLeft(MediaSfuParticipantEvent change)
{
RefreshParticipantList();
}
CurrentRoom.Participants is the current membership snapshot. It confirms who
is in the room, not that a remote video texture or audio output is working.
Connect media in a deliberate order
Use the following operations after a room exists:
var connected = await client.ConnectMediaAsync();
if (!connected.Success)
{
ShowRoomError(connected.Error);
return;
}
var permission = await client.RequestMediaPermissionAsync(MediaSfuTrackKind.Video);
if (!permission.Success)
{
ShowPermissionState(permission.Error);
return;
}
ConnectMediaAsync establishes the signaling and room validation path.
RequestMediaPermissionAsync requests host approval when the room policy
requires it. Neither result proves that a camera has started; check the local
media backend and confirm playback in another Unity player.
For a custom WebRTC workflow, the exact track operations are:
MediaSfuOperationResult<MediaSfuProduceResponse> produced =
await client.ProduceMediaTrackAsync(produceRequest);
MediaSfuOperationResult<MediaSfuConsumeResponse> consumed =
await client.ConsumeMediaTrackAsync(consumeRequest);
Build produceRequest and consumeRequest from the active transport and
attached WebRTC device. Do not invent IDs or reuse a request from an earlier
room. A successful producer result means the client accepted that operation;
verify the actual remote track in a second player.
Screen share, leave, and host end
var share = await client.SetScreenShareEnabledAsync(true);
if (!share.Success)
ShowRoomError(share.Error);
var leaveAndKeepOpen = await client.LeaveRoomAsync(endRoomOnHostExit: false);
if (!leaveAndKeepOpen.Success)
ShowRoomError(leaveAndKeepOpen.Error);
var ended = await client.EndMeetingAsync();
if (!ended.Success)
ShowRoomError(ended.Error);
SetScreenShareEnabledAsync(true) requires a supported local capture backend,
the required platform permission, and any room approval. Call it with false
when sharing ends.
LeaveRoomAsync() retains its historical endRoomOnHostExit: true default.
Passing false lets a host leave while the room and remaining participants
continue. EndMeetingAsync is the explicit host-only end-room request; it
requires an active socket and a local host role. After any exit call, stop
app-owned local tracks, remove event subscriptions, clear scene state, and only
then navigate away from the room scene.
Handle failures without guessing
| Result | What to do |
|---|---|
| Room request is denied | Explain that the player is not allowed to enter or create this room; do not retry with a client secret. |
ConnectMediaAsync fails | Keep the player on a recoverable connection screen and offer a bounded retry after checking network access. |
| Permission request is denied | Explain which capability is unavailable and keep the player in control of device settings. |
| Produce, consume, or screen share fails | Preserve the room UI, stop any partial app-owned capture, and show the operation result message. |
| Host end is denied | Keep the room running and show that only the current host with an active connection can end it. |
Release checklist
- Test authenticated create and join policy through your application backend.
- Test participant joins and leaves with two Unity players.
- Test microphone, camera, remote audio/video, and permission denial on each supported platform.
- Test screen-share start, stop, denial, and cleanup where the platform supports capture.
- Test participant leave and host end separately, including stale event subscription and local-track cleanup.
- Do not log room authority, player identity tokens, or media metadata.
Compile and test the application for every target player. Then repeat the release checklist in the Unity Editor and on real target hardware; an Editor or managed-code test cannot prove native capture, rendering, audio routing, or screen sharing.