The GameAnvilConnector provides a simple way to synchronize the creation/destruction, Transform, Animation, Rigidbody2D, and Rigidbody properties of GameObjects.
Simply attach the Sync, TransformSync, AnimatorSync, Rigidbody2DSync, and RigidbodySync components to the GameObjects you want to synchronize, respectively, and their properties will be synchronized.
It is important to note that GameObjects that want to use the Sync Component must also have a Sync Component added to them, but this is not a concern as the implementation will automatically add them together when you attach each Sync Component if they do not have the necessary components, including the Sync Component.
When one client changes certain properties, a sync request packet is sent, and the server broadcasts it to all users in the same room so that they can synchronize on other clients.
The SyncController must exist in the scene where you want to use the Sync feature. It plays a key role in the behavior of the Sync feature, including the Instantiate() and Destroy() functions that create and destroy Synchronized GameObjects.
Create a GameObject and add the SyncController component. You can add it as a component by choosing Add Component > GameAnvil > SyncController.
Alternatively, you can create one directly from the Unity Hierarchy by right-clicking and selecting GameAnvil > SyncController.
If you want to synchronize the creation/destruction of GameObjects, you can attach the Sync component to any GameObject to synchronize the creation/destruction of mutually created GameObjects between users in the same room. You can add it as a component by selecting Add Component > GameAnvil > GameAnvil Sync > Sync.
Each user is given a unique sync key, each GameObject is given an object ID, and all user-specific synchronized GameObjects are distinguished by a sync ID generated by combining the two.
Sync.SyncId to get the sync ID of the synchronizing GameObject.
Indicates how the synchronized GameObject was created. It is marked LOCAL for GameObjects created directly by the client, or REMOTE for GameObjects created by another client that are also created in your scene by synchronizing their creation.
You can prefab a GameObject with a Sync component attached to it and save it under the Assets/Resources folder in Unity. Then, when you enter a room, you can use the SyncController's Instantiate() method to create that prefab at any point in time.
Note that you must be in the room to create a GameObject with synchronized creation/destruction.
/// <summary>
/// Creates a Synchronization GameObject.
/// </summary>
/// <param name="prefabName">The name of the prefab to create. The prefab must exist under the Assets/Resources folder.</param>
/// <param name="v">The position to create the prefab at</param>
/// <param name="r">rotation of the prefab</param>
/// <returns></returns>
public GameObject Instantiate(string prefabName, Vector3 v, Quaternion r);
Options | Description |
---|---|
InstantiateSyncObjectImmediatly | If true, synchronize immediately after the user enters the room; if false, don't synchronize immediately and call the sync function directly instead. |
When a user enters a room, SyncController.roomSyncStart() is called in the callback that is called after the user enters the room to create and synchronize GameObjects using the existing room's sync data received from the server.
However, if you don't want to synchronize immediately after entering a room, you can set the SyncController's InstantiateSyncObjectImmediatly option to false and call SyncController.InstantiateSyncObject() at the desired time.
When a GameObject with a Sync component attached to it is destroyed, the destruction synchronization is handled in the onDestroy() function so that the GameObject disappears from other users' scenes as well.
The current specification is that when a user enters a room, creates synchronized GameObjects, and then moves around the scene, all of the GameObjects are destroyed and the data stored on the server while synchronizing them is deleted.
This means that when you move to a different scene and come back to the original scene, you may find that the synchronized GameObjects you created are missing, and if you move the scene on one client and all of the synchronized GameObjects are destroyed, the destructive synchronization may cause them to be destroyed on the other client as well. This is something that will be fixed in the next specification.
You can attach the TransformSync component to any GameObject that you want to synchronize its Transforms to synchronize the Transforms of the synchronizing GameObject. You can add it as a component by selecting Add Component > GameAnvil > GameAnvil Sync > TransformSync. Sync components are automatically added together.
Create a prefab GameObject with the TransformSync component attached to it and save it under the Assets/Resources folder in Unity.
When you enter a room, create that prefab via Instantiate() in the SyncController, and then change the Transform, you'll see that all other clients synchronize to the changed Transform.
You can optionally select which properties to synchronize during the transformation.
Options | Description |
---|---|
Synchronize Position | Sets whether to synchronize the Position property: true to synchronize the Position value, false to not synchronize the Position value. |
Synchronize Rotation | Sets whether to synchronize the Rotation property: true to synchronize Rotation values, false to not synchronize Rotation values. |
Synchronize Scale | Sets whether to synchronize the Scale property: true to synchronize the Scale value, false to not synchronize the Scale value. |
Use Local | Sets whether localPosition and localRotation should be used. Scale ignores this setting and always uses localScale to avoid issues with lossyScale. |
You can attach the AnimatorSync component to any GameObject that you want to synchronize animations to, and change the Animation State by changing the value of the Animator's parameters, and those changes will be synchronized on other clients. You can add it as a component by choosing Add Component > GameAnvil > GameAnvil Sync > AnimatorSync. The Sync and Animator components are automatically added together.
Create a prefab GameObject with an AnimatorSync component attached to it and save it under the Assets/Resources folder in Unity.
When you enter a room, create that prefab via Instantiate() in the SyncController, and then change the Animation, you'll see that all other clients synchronize to the changed Animation.
Attaching the Rigidbody2DSync component to the GameObject you want to synchronize the Rigidbody2D with will synchronize the Rigidbody2D of the synchronizing GameObject. You can add it as a component by choosing Add Component > GameAnvil > GameAnvil Sync > Rigidbody2DSync. The Sync, TransformSync, and Rigidbody2D components are automatically added together.
Create a GameObject prefab with the Rigidbody2DSync component attached to it and save it under the Assets/Resources folder in Unity.
When you enter the room, create that prefab via Instantiate() in the SyncController, and then change the Rigidbody2D, you will see that all other clients synchronize to the changed Rigidbody2D.
You can optionally select which properties of the Rigidbody2D you want to synchronize.
Options | Description |
---|---|
Synchronize Velocity | Sets whether to synchronize the Velocity property: true to synchronize the Velocity value, false to not synchronize the Velocity value. |
Synchronize Angular Velocity | Sets whether to synchronize the Angular Velocity property: true to synchronize Angular Velocity values, false to not synchronize Angular Velocity values. |
Teleport Enabled | Set whether to allow teleportation. |
Teleport if distance greater than | If the distance differs by more than a set threshold, we apply the Position value to the Rigidbody2D's Position to synchronize to, and then synchronize using the Velocity value. |
Teleport if angle greater than | If the angle varies by more than a set threshold, we apply the angle value we want to synchronize to the Rigidbody2D's Rotation and then synchronize using the Angular Velocity value. |
The RigidbodySync component can be attached to any GameObject that you want to synchronize RigidBodies to synchronize the RigidBodies of the synchronizing GameObject. You can add it as a component by choosing Add Component > GameAnvil > GameAnvil Sync > RigidbodySync. The Sync, TransformSync, and Rigidbody components are automatically added together.
Create a prefab GameObject with the RigidbodySync component attached to it and save it under the Assets/Resources folder in Unity.
When you enter the room, create that prefab via Instantiate() in the SyncController, and then change the Rigidbody, you'll see that all other clients synchronize to the changed Rigidbody.
You can optionally select which properties of the Rigidbody you want to synchronize.
Options | Description |
---|---|
Synchronize Velocity | Sets whether to synchronize the Velocity property: true to synchronize the Velocity value, false to not synchronize the Velocity value. |
Synchronize Angular Velocity | Sets whether to synchronize the Angular Velocity property: true to synchronize Angular Velocity values, false to not synchronize Angular Velocity values. |
Teleport Enabled | Set whether to allow teleportation. |
Teleport if distance greater than | If the distance differs by more than a set threshold, we apply the Position value to the Rigidbody's Position to synchronize to, and then synchronize using the Velocity value. |
Teleport if angle greater than | If the angle varies by more than a set threshold, we apply the angle value we want to synchronize to the Rigidbody's Rotation and then synchronize using the Angular Velocity value. |
Provides the ability to synchronize user-defined values of type int, float, bool, and string.
You can add or change a custom value with SyncController.SetCustomProperty
/// <summary>
/// Adds a user-defined value.
/// </summary>
/// <typeparam name="T">Type of custom value</typeparam>
/// <param name="key">Key to distinguish the custom value</param>
/// <param name="value">Custom value</param>
public static void SetCustomProperty<T>(string key, T value);
Let's look at a usage example.
SyncController.SetCustomProperty<float>("custom_key", 0.9f);
When you call SyncController.SetCustomPropertyCAS
The server then compares the custom value previously stored on the client with the custom value obtained as a distinguishing key from the data stored on the server.
If they are the same, we assume that the client's custom values were up to date and synchronized, so we replace them with the desired values, store them on the server, and broadcast them to other users so they can also synchronize.
If the custom value stored on the client is different from the value stored on the server, the request is ignored.
/// <summary>
/// Checks if user-defined values are up to date before changing them.
/// </summary>
/// <typeparam name="T">Type of custom value</typeparam>
/// <param name="key">Key to distinguish the custom value</param>
/// <param name="value">Custom value</param>
public static void SetCustomPropertyCAS<T>(string key, T value);
Let's look at a usage example.
SyncController.SetCustomPropertyCAS<float>("custom_key", 0.9f);
You can get a custom value with SyncController.GetCustomProperty
/// <summary>
/// Retrieves a user-defined value.
/// </summary>
/// <typeparam name="T">Type of custom value</typeparam>
/// <param name="key">Key to distinguish the custom value</param>
/// <returns>Custom value</returns>
public static T GetCustomProperty<T>(string key);
Let's look at a usage example.
float custom_value = SyncController.GetCustomProperty<float>("custom_key");
You can delete a custom value with SyncController.RemoveCustomProperty
/// <summary>
/// Deletes a user-defined value.
/// </summary>
/// <param name="key">Key to distinguish between custom values</param>
public static void RemoveCustomProperty(string key)
Let's look at a usage example.
SyncController.RemoveCustomProperty("custom_key");