Bolt 104 - Objects & Arrays

Bolt supports built-in replication of complex types called objects and arrays, they are very similar to their plain code C# counterparts, but differ in a few ways. Objects are defined in the 'Bolt Assets' window and can be used as the type for an 'Array' or 'Object' property on a state or another object.

Objects gives you an easy mechanism to encapsulate a group of properties and allows you to implement complex hierarchical data in Bolt that is easily re-usable across different Bolt states. We are going to demonstrate how to use objects inside Bolt by implementing weapon slots for a simple shooter game, we are not going to actually build a game just the data structure and states to replicate the weapons.

Start by creating a new 'Object' in the 'Bolt Assets' window using the right-click menu.

Name the object 'WeaponSlot', and give it two properties: 'WeaponId' and 'WeaponAmmo'. They should both be integers. As you can see the objects in Bolt do not have properties of their own like the events and states, they are simply containers for data that can be included in other assets.

On our 'CubeState' we are now going to add a new property called 'WeaponsArray' that has the type 'Array', the 'Element Type' set to 'Object', the 'Object Type' set to 'WeaponSlot' and we're going to give it an 'Element Count' of 3. We're also going to add one more property called 'WeaponActiveIndex' which should have the type 'Integer'. This is for tracking which weapon we have active.

Important: As always, remember to compile Bolt after we are done with our changes in the 'Bolt Assets' and 'Bolt Editor' windows.

The 'WeaponsArray' property is by far the most complex we have created so far, what Bolt will create an array of three 'WeaponSlot' objects for us, which we then can modify and have all of their data automatically replicate over the network.

Note that when we say 'array' here we don't mean an actual C# WeaponSlot[] array, Bolt provides its own array-like type which lets Bolt track changes made to objects easily. The actual type of the 'WeaponSlots' property will be Bolt.NetworkArray_Objects<WeaponSlot>, in general you can mostly ignore this as the normal indexing operations work on this class also and it has the same Length property, etc.

It's time to setup some very simple place-holder weapons for our 'Cube' prefab, drag a copy of the prefab into an empty scene, make sure it's positioned at (0, 0, 0) in the scene. Create a new sphere, capsule and cylinder at (0, 0, 0) also and make them children of the 'Cube'. Remove the default colliders from them also. The transform settings I used for them are as follows:

  1. Sphere & Cylinder

    • Position: 0, 0, -0.75
    • Rotation: 0, 0, 0,
    • Scale: 0.4, 0.4, 0.4
  2. Capsule

    • Position: 0, 0, -1
    • Rotation: 90, 0, 0
    • Scale: 0.4, 0.4, 0.4

This simply gives us an easy way to see which weapon we have active currently. Make sure to apply the changes to the prefab either by hitting 'Apply at the top of the inspector when the 'Cube' is Selected or simply by dragging in the 'Cube' in the scene into the 'Cube' prefab in the 'Project' window.

At the top of our CubeBehaviour script we are now going to add a new variable called WeaponObjects which is an array of unity GameObject.

Go into the inspector for our 'Cube' prefab and drag the three child objects into the 'WeaponObjects' array inspector field.

Also make sure to disable the three 'Sphere', 'Capsule' and 'Cylinder' objects so that they are all off by default.

We're going to add quite a lot of new code to our CubeBehaviour script now, to get our weapons setup properly we need to setup the weapons for each player on the owner, inside Attached. We also need to hook up a callback so we get a notification when the active weapon slot changes.

There's a new for loop inside the if(entity.isOwner) block which lets us initialize the three weapon slots, here we use the WeaponsArray property we defined on our state in the 'Bolt Assets' window. As you can see it functions mostly like a normal array. We randomly assign one of the weapon object models to .WeaponId and then we randomly pick an ammo count between 50 and 100 and assign it to .WeaponAmmo.

We also set the .WeaponActiveIndex property to -1, meaning that we don't have a weapon up by default. The last thing we do is at the end where we add a callback to the "WeaponActiveIndex" property so that we get a notification when the active weapon changes.

The WeaponActiveIndexChanged method looks like this.

The first thing we do is to just disable all weapon objects, we then check if our index is >= 0 and if it is we grab the .WeaponId and use that to enable the correct object to show. The last thing we need to do is just polling some standard Unity input in SimulateOwner, like this:

We add that after the piece of code which polls the WSAD keys in SimulateController:

The complete CubeBehaviour script now looks like this.

If you build your game and start a server and client, you will be able to pick a weapon using the 1, 2 and 3 keys on the keyboard, and it should look something like this.

If you hover over any of the cubes you will be able to see the state of the weapon properties we setup.

Currently we are not using the WeaponAmmo property for anything, but you can still see the value of it.

 To Document Top