a. Get things moving

First, you'll add some movement to the player and then to the spheres.

Add a player movement script

First, create a PlayerInputBehaviour.cs script inside the BlankProject > Scripts > Player folder where the SphereSpawnerBehaviour currently resides. Copy the code below into the file and save.

using Improbable;
using Improbable.Gdk.Subscriptions;
using UnityEngine;

namespace Scripts.Player
{
    public class PlayerInputBehaviour : MonoBehaviour
    {
        // To check we're authoritative over this player
        [Require] private PositionWriter positionWriter;

        public float defaultSpeed = 5f;

        // Cache the main camera's transform
        private Transform mainCameraTransform;

        private void OnEnable()
        {
            mainCameraTransform = UnityEngine.Camera.main.transform;
        }

        private void Update()
        {
            var h = Input.GetAxisRaw("Horizontal");
            var v = Input.GetAxisRaw("Vertical");

            var forward = mainCameraTransform.forward;
            var right = mainCameraTransform.right;
            forward.y = 0f;
            right.y = 0f;
            forward.Normalize();
            right.Normalize();

            var direction = (forward * v) + (right * h);
            var speed = Input.GetKey(KeyCode.LeftShift)
                ? 2 * defaultSpeed
                : defaultSpeed;

            transform.Translate(speed * Time.deltaTime * direction);
        }
    }
}

This script modifies a player’s Unity transform to move in the direction the camera is facing at a certain speed, with a double speed boost if the left shift key is pressed. Similar to the FollowPlayerCamera script, this script requires a PositionWriter to make sure that this behaviour only works on the client-worker authoritative over a given player.

Test player movement

Add the PlayerInputBehaviour to the client-side Player prefab. Launch a local deployment (Ctrl+L on Windows or Cmd+L on Mac) and press the play button in the Editor.

After moving your Player in the world, open the Scene view and observe how your Player object has moved in the client level, but not in the server level. This is expected for now as the Transform Synchronization Feature Module has not been set up yet, so local movement is not sent to SpatialOS or the server.

Create a sphere movement script

Now that you have player movement, let’s add sphere movement. Inside BlankProject > Scripts, create a “Sphere” folder. Within that, create a SphereMovementBehaviour script and copy the code below into it.

using System.Collections;
using Improbable;
using Improbable.Gdk.Subscriptions;
using UnityEngine;

namespace Scripts.Sphere
{
    public class SphereMovementBehaviour : MonoBehaviour
    {
        // to ensure we are authoritative
        [Require] private PositionWriter positionWriter;

        [SerializeField] private float forcePerPush = 1000f;
        [SerializeField] private float pushInterval = 5f;

        private Rigidbody rigidbody;
        private Vector3 workerOrigin;

        private Coroutine applyForceCoroutine;

        private void OnEnable()
        {
            rigidbody = GetComponent<Rigidbody>();
            workerOrigin = GetComponent<LinkedEntityComponent>().Worker.Origin;

            applyForceCoroutine = StartCoroutine(ApplyForce());
        }

        private void OnDisable()
        {
            StopCoroutine(applyForceCoroutine);
        }

        IEnumerator ApplyForce()
        {
            while (true)
            {
                yield return new WaitForSeconds(pushInterval);

                if (rigidbody != null)
                {
                    var direction = (workerOrigin - transform.position).normalized;
                    rigidbody.AddForce(forcePerPush * direction);
                }
            }
        }
    }
}

Unlike the player movement, we want spheres to move at a given interval. Instead of modifying the transform, we are treating spheres as physical objects that we can apply a force to. The goal is to apply a “push” with a constant force on each sphere towards the origin.

The [SerializeField] attribute is added to both forcePerPush and pushInterval fields to allow easier tweaking of movement in-game.

Since sphere movement is server-authoritative, a PositionWriter is required to ensure that this movement is only applied on workers that are authoritative over the Position of a given sphere.

Making the spheres move

Add the SphereMovementBehaviour script and the Rigidbody to the Sphere prefab. Restart your local deployment and hit the Editor’s play button. You should notice that, similar to the Player, the spheres are only moving on one of the workers.

Movement is not being replicated across workers because the Transform Synchronization module has not been set up. This is why objects are only moving on the level of their respective authoritative workers. Player movement is client-authoritative, so the player only moves on the client-level. Sphere movement is server-authoritative, so spheres only move on the server-level.

How do you know data is not being sent, rather than the receiver not applying changes?

You can use the Worker Inspector to validate the data isn’t being sent to SpatialOS and rule out the possibility that the receiver isn’t applying changes. The Worker Inspector allows you to inspect the state of your workers in-Editor.

The window allows you to view the set of entities each worker is interested in, as well as the data and authority state of components on each entity. Therefore if components aren’t updating for sphere entities, we’ll know that data is not being sent to SpatialOS.

Select SpatialOS > Windows > Worker Inspector from the menu to open the Worker Inspector.

Pick a specific entity on the client-worker, and observe that the Position component never changes.

The same can be observed on the server-worker for the same entity.

The Worker Inspector is therefore showing that while the objects on each level move, the entity’s component never changes which means that movement is never replicated.

Updated about a year ago


a. Get things moving


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.