Getting Started

Introduction

Installation

Project Configuration

Testing in Your Sandbox

Samples & Examples

Core Concepts & Glossary

Package Types

Spaces & Space Templates

Custom Avatars

Custom Avatar Animations

Avatar Attachments

Custom Prefab Objects

Embedded Packages

Drivable Vehicles

Scene Setup

Testing In Unity vs Sandbox

Controlling the Camera

Custom Collision, Layers, and Tags

Audio Mixers and Groups

Key Differences from Standard Unity3D development

Economy

Quests and Rewards

Economy Overview

Monetization

Items

Consumable Items

Rewarding Items

World Currency

Selling Items

Scripting

Components

Entrance Point

Camera Passthrough

Interactable

Trigger Event

Point Of Interest

Environment Settings Overrides

Render Pipeline Settings Overrides

Movement Materials

Climbable

Avatar Teleporter

Empty Frame

Projector Surface

Seat Hotspot

Guidelines

Supported Features and Limitations

Performance Guidelines

Lighting

Publishing to Spatial

Finding Published Packages

Support

FAQs

Help and Support

Release Notes

Asset Import Settings

Spatial Netcode Introduction

<aside> <img src="/icons/emoji-winking_yellow.svg" alt="/icons/emoji-winking_yellow.svg" width="40px" /> Multiplayer networking is an advanced topic. If you are new to Unity or programming we recommend you get comfortable with the basics of Visual Scripting first.

</aside>

Vocabulary


Client

A single connected user in a space. Each avatar in a space represents a single client*.*

Ownership

Responsibility for certain objects or state in a space.

State

Overarching term to describe data like transform positions and custom variables. State can be synced or un-synced depending on the context.

State is king


In Spatial, clients are synced through state updates. This means when a client modifies the position of a synced object for example, all other clients will receive a message like:

Object [Baseball]’s new position = (100,0,0)

Each client will then set the position of their matching [Baseball] instance to match. In other words, the results of your code is synced rather than the code itself.

Object ownership and takeover


In Spatial, each Synced Object is owned by a single client*.* Only state changes made by the owner of the object will propagate to the rest of the connected clients.

By default the original creator of an object is the owner. However, clients can request to takeover ownership of an object. Ownership lasts until the client disconnects, or another client requests ownership. When the owner of an object disconnects ownership is defaulted to one of the other connected clients.

<aside> <img src="/icons/hand_yellow.svg" alt="/icons/hand_yellow.svg" width="40px" /> If a client tries to modify the state of a synced object that they do not own, the change will be reverted during the next frame.

</aside>

Object lifetime


The principles above also apply to the life of a synced object.

If a client Instantiates a synced object, all connected clients will create an instance of the same object locally.

If a client Destroys a synced object that they own, all connected clients will destroy their instance of the same object.

If a client Destroys a synced object that they don’t own, the object will be re-created to match the current synced state.

Synced Object Example


Using the above rules as guidance, let’s create a simple example where we take into account object ownership to create a properly coded synced object.

I want to make an object that follows a user around, but another user can “grab” it, in which it will follow that user instead.

Step 1


To get started we need to add a Synced Object component as well as a script machine to our object. The object in question is a scene object, so we don’t need to worry about instantiating it.

Untitled

Step 2


Inside our script we first want to write the code that updates the objects position. Remember that only the client that owns the object should be modifying the transform state.

To accomplish this we use the If Owned Locally synced object node. This lets us branch off the true port, causing the subsequent code to only be run when the local client owns the object.

The result of this will be an object that follows its owner.

Untitled

Step 3


Now we need to add the ability to claim ownership of the object. I accomplished this through adding a Spatial Interactable as a child to the object.

Then in VS we can use an On Interact event and trigger the Takeover Ownership synced object node. This means when a client uses the interactable, they will become the owner of the object.

Untitled

Untitled

Step 4


Now we can actually improve this a little further. By using the On Owner Changed synced object event, we can enable/disable the interactable to only be visible when we don’t own it.

Untitled

← Previous

Servers and Matchmaking

Next →

Synced Animator