Sync Entity
The SyncEntity class is the scripting foundation for syncing data in a Lens. A SyncEntity connects a script to a Realtime Store, letting the script manage the state of the entity, including synced data.
Creating a New SyncEntity
Creating a new SyncEntity is as simple as calling the SyncEntity constructor. The script component associated with the SyncEntity is passed as a required parameter.
- TypeScript
- JavaScript
const syncEntity: SyncEntity = new SyncEntity(this);
const syncEntity = new SyncEntity(script);
The constructor also accepts the following optional parameters:
storagePropertySet: StoragePropertySetclaimOwnership: boolean, see Ownershippersistence: RealtimeStoreCreateOptions.Persistence, see PersistencenetworkIdOptions: NetworkIdOptions
- TypeScript
- JavaScript
this.syncEntity: SyncEntity = new SyncEntity(this, null, true, "Session", null)
const syncEntity = new SyncEntity(script, null, true, 'Session', null);
Getting an Existing SyncEntity
There may be cases where a scene object already has a script with a sync entity attached to it, such as a SyncTransform component. In this case, the existing SyncEntity can be accessed from another script, instead of creating a new one.
A SyncEntity can be found on a scene object by calling:
- TypeScript
- JavaScript
this.syncEntity = SyncEntity.getSyncEntityOnSceneObject(this.getSceneObject());
const syncEntity = SyncEntity.getSyncEntityOnSceneObject(
script.getSceneObject()
);
A SyncEntity can be found on a component by calling:
- TypeScript
- JavaScript
this.syncEntity = SyncEntity.getSyncEntityOnComponent(scriptComponent);
const syncEntity = SyncEntity.getSyncEntityOnComponent(scriptComponent);
If no SyncEntity is found, null is returned.
SyncEntity Setup
Before a SyncEntity is fully available for use, it needs to finish its setup process. This includes:
- Waiting for the multiplayer session to connect.
- Connecting to its existing Realtime Store, or creating a new one if none is found.
It is important that setup is finished before data is accessed from the SyncEntity. To check that a SyncEntity is ready to use, call SyncEntity.notifyOnReady(). The method accepts a callback function that runs once the SyncEntity is ready. If setup is already finished, the callback function executes immediately.
- TypeScript
- JavaScript
onReady() {
print('The session has started and this entity is ready!')
// Start your entity's behavior here!
}
this.syncEntity.notifyOnReady(() => this.onReady())
function onReady() {
print('The session has started and this entity is ready!');
// Start your entity's behavior here!
}
syncEntity.notifyOnReady(onReady);
You can also check if setup has completed by checking SyncEntity.isSetupFinished, which is a boolean.
- TypeScript
- JavaScript
if (this.syncEntity.isSetupFinished) {
// Setup is finished
}
if (syncEntity.isSetupFinished) {
// Setup is finished
}
Many actions are completely fine to do before setup is finished, such as subscribing to events, adding storage properties, or subscribing to storage property changes. You can even preemptively request ownership before setup is finished. It is generally good practice to wait until setup has completed before starting any SyncEntity behavior like sending networked events, or modifying storage properties.
Ownership
Each SyncEntity can either have an owner or be unowned. If a SyncEntity is owned, only the owner is allowed to modify its values. If a SyncEntity is unowned, any user can modify the values. Ownership follows the same rules as Realtime Store ownership.
Request Ownership
There are multiple ways to request ownership of a SyncEntity, either when the entity is created or afterward.
Request Ownership on Creation
Ownership can be requested while constructing the SyncEntity by passing a requestOwnership boolean as the third parameter. To request ownership, pass true.
- TypeScript
- JavaScript
this.syncEntity = new SyncEntity(this, null, true);
const syncEntity = new SyncEntity(script, null, true);
If the SyncEntity is already owned, the ownership request will be added to a queue and tried again whenever the entity becomes unowned.
After the SyncEntity has been created, ownership can either be requested with a one-time request, or as a queued request.
One-Time Ownership Request
To do a one-time ownership request, use SyncEntity.requestOwnership(). The method accepts onSuccess and onError callbacks as parameters. This will immediately callback with success if the local user already owns it. If the SyncEntity is unowned, ownership is granted and the success callback runs. If the SyncEntity is already owned, the request is not granted and nothing further happens. If an error occurs during the request, the error callback runs.
- TypeScript
- JavaScript
onSuccess() {
print("Ownership claimed");
}
onError() {
print("Error, ownership not claimed);
}
this.syncEntity.requestOwnership(this.onSuccess, this.onError)
function onSuccess() {
print("Ownership claimed");
}
function onError() {
print("Error, ownership not claimed);
}
syncEntity.requestOwnership(onSuccess, onError);
Queued Ownership Request
Alternatively, ownership requests can be placed in a queue and granted when the SyncEntity becomes unowned. This is done by calling SyncEntity.tryClaimOwnership(), which also takes onSuccess and onError callbacks as parameters. This will also immediately callback with success if the local user already owns it. This places the request in a queue, and the SyncEntity will continue to try gaining ownership whenever the SyncEntity becomes unowned. If the SyncEntity has not yet finished setup when this function is called, the ownership request will be put into the queue so that ownership can be requested as soon as possible.
- TypeScript
- JavaScript
onSuccess() {
print("Ownership claimed")
}
onError() {
print("Error, ownership not claimed)
}
this.syncEntity.tryClaimOwnership(this.onSuccess, this.onError)
function onSuccess() {
print("Ownership claimed");
}
function onError() {
print("Error, ownership not claimed);
}
syncEntity.tryClaimOwnership(onSuccess, onError);
Revoke Ownership
Ownership of a SyncEntity can be revoked using SyncEntity.tryRevokeOwnership(). The method accepts optional onSuccess and onError callbacks as parameters. This will immediately callback with success if the local user does not own the SyncEntity.
- TypeScript
- JavaScript
this.syncEntity.tryRevokeOwnership(() => {
print('Ownership revoked');
});
syncEntity.tryRevokeOwnership(function () {
print('Ownership revoked');
});
Check Ownership
Check if the SyncEntity’s Realtime Store is owned using SyncEntity.isStoreOwned().
- TypeScript
- JavaScript
if (this.syncEntity.isStoreOwned()) {
print('Store is owned');
}
if (syncEntity.isStoreOwned()) {
print('Store is owned');
}
Check if the local user owns the SyncEntity’s Realtime Store using SyncEntity.doIOwnStore().
- TypeScript
- JavaScript
if (this.syncEntity.doIOwnStore()) {
print('I own the store');
}
if (syncEntity.doIOwnStore()) {
print('I own the store');
}
Check if the local user is allowed to modify the SyncEntity’s Realtime Store using SyncEntity.canIModifyStore().
- TypeScript
- JavaScript
if (this.syncEntity.canIModifyStore()) {
this.syncEntity.requestOwnership();
}
if (syncEntity.canIModifyStore()) {
syncEntity.requestOwnership();
}
To get the current owner’s UserInfo, use SyncEntity.ownerInfo. This can return null, or be a UserInfo object with null fields if the SyncEntity is unowned.
- TypeScript
- JavaScript
const owner = this.syncEntity.ownerInfo.displayName;
print('Store is owned by ' + owner);
const owner = syncEntity.ownerInfo.displayName;
print('Store is owned by ' + owner);