c. Dynamic sphere spawning

Now that we’ve added some spheres to our snapshot, let’s take a look at how to spawn more spheres dynamically at runtime. We can reuse our CreateSphereTemplate method along with the CreateEntity world command to accomplish this.

What’s a world command?

A world command is a special type of command which you send to the Runtime, rather than an entity. In this case, the CreateEntity command asks the Runtime to create a new entity with the components and data specified in an EntityTemplate.

We’re going to add a behaviour to our player where if you press ‘spacebar’ on your keyboard, it should spawn a new sphere in the world.

Create the behaviour

First things first, let’s create a new MonoBehaviour to encapsulate this behaviour. From the Assets window in the Unity Editor, navigate to the BlankProject/Scripts/Player folder and create a new C# Script called SphereSpawnerBehaviour.

Initially, we will write this script to print a debug log when the user presses the spacebar to make sure we have wired everything up correctly. Later, we will send the command instead of printing a debug log.

Copy the following code into the file:

using BlankProject;
using BlankProject.Scripts.Config;
using Improbable;
using Improbable.Gdk.Core;
using Improbable.Gdk.Core.Commands;
using Improbable.Gdk.Subscriptions;
using UnityEngine;
using Random = UnityEngine.Random;

namespace Scripts.Player
{
    [WorkerType(UnityClientConnector.WorkerType)]
    public class SphereSpawnerBehaviour : MonoBehaviour
    {
        [Require] private PositionWriter positionWriter;
        [Require] private WorldCommandSender worldCommandSender;

        private void Update()
        {
            if (Input.GetKeyDown(KeyCode.Space))
            {
                SendSpawnSphereCommand();
            }
        }

        private void SendSpawnSphereCommand()
        {
            Debug.Log("Pressed spacebar!");
        }
    }
}

Let’s break this down, as there are a few new concepts:

  1. The [Require] attribute. This attribute denotes that the field will be injected dynamically by the GDK when the underlying conditions for that field are met. These conditions vary by what type of object is being injected. If a GameObject that is used in one or more EntityRepresentationMapping assets has a MonoBehaviour which has any fields with [Require] on them, the GDK will disable the behaviour at build time (or right before you enter Playmode if in the Editor). When all required fields have their conditions met, they will be injected into the behaviour and the behaviour will be enabled. Conversely if any required fields stop having its conditions met, all required fields are uninjected and the behaviour will be disabled.
  2. The WorldCommandSender field. This object allows you to send and receive responses to world commands, like CreateEntity. There is no condition for injection and should always be available.
  3. The PositionWriter field. This object allows you to read & write to the Position component on an entity. The conditions for injection are that the underlying SpatialOS entity has both the Position component ‘checked out’ on this worker and that this worker is authoritative over the Position component.

Why do we need the `PositionWriter`?

We need the PositionWriter field to constrain this script to only run on authoritative players.

If you were to omit this field, this script would run on every player that each worker has checked out. That means that when the player presses the spacebar, we would spawn a sphere for each player that the worker has checked out.

By adding the PositionWriter we ensure that it only runs on your own player, as you will only be authoritative over your own player’s Position and not other players’ Position.

Add the script to the Player Prefab

Let’s now add the behaviour to our Player Prefab and test out our changes!

Navigate to the Prefabs/Entities/UnityClient/ directory and select the Player Prefab to open it in the Inspector.

Select ‘Add Component’ and add the SphereSpawnerBehaviour to this Prefab.

Hit Ctrl+L on Windows or Cmd+L on MacOS to launch a local deployment. When your local instance of SpatialOS is ready, select Play in the Editor. Once your player spawns, press the spacebar a few times and make sure “Pressed spacebar!” is printed in the Unity Editor Console.

Finish up the script

Now that we’ve validated that the script is running correctly on our player, let’s make the behaviour spawn spheres instead of printing logs.

Open the SphereSpawnerBehaviour again, and replace the SendSpawnSphereCommand function with the following:

private void SendSpawnSphereCommand()
{
    var randomPosition = new Vector3
    {
        x = Random.Range(-50f, 50f),
        y = Random.Range(0.5f, 5f),
        z = Random.Range(-50f, 50f)
    };

    var sphereTemplate = EntityTemplates.CreateSphereTemplate(randomPosition);

    worldCommandSender.SendCreateEntityCommand(new WorldCommands.CreateEntity.Request(sphereTemplate));
}

In this function, we are now generating a random position for the sphere, reusing the CreateSphereTemplate function we defined earlier to get an entity template for our sphere, and are sending a CreateEntity command for that sphere. Let’s test it out!

You can repeat the test from the previous step, but instead of printing logs to the Unity Editor Console, you should see more spheres appear in the world!

Persistence of the new spheres

Any spheres created in this manner only exist for the lifetime of the deployment. You can observe this by creating a few spheres, then restarting the local deployment. After restarting the deployment, the spheres you created won’t exist anymore.

When the local deployment starts, it uses the snapshot as the initial state. Since our dynamically created entities are not defined in our snapshot, restarting the deployment means they will no longer exist in your game.

Updated about a year ago



c. Dynamic sphere spawning


Suggested Edits are limited on API Reference Pages

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