UCL-VR / ubiq

Other
98 stars 34 forks source link

NetworkSpawner Improvements #45

Open sebjf opened 8 months ago

sebjf commented 8 months ago

This PR resolves https://github.com/UCL-VR/ubiq/issues/41

It makes a number of quality of life changes to the Network Spawning functionality.

The biggest changes are:

  1. The Catalogues entry on NetworkSpawnManager is now a List, allowing users to create and add their own Catalogues on a per-scene basis.

Prefabs ids are now strings, assigned on startup. Changing them at runtime is not supported. The actual Catalogues member is now private preventing the lists from being accessed directly; code should use the GameObject references themselves now throughout.

  1. SpawnWithRoomScope and SpawnWithPeerScope now take an optional string, which is associated with the spawned instance. This string is passed with new instances of a Prefab in OnSpawned.

The idea is that this string can be used to hold additional properties to configure a Prefab. This is motivated by the Cake Decoration cw submission, for which needed to spawn one Prefab with various different colours controlled by the user at runtime.

As UnityEvents only allow 4 generic arguments, the NetworkSpawnOrigin parameter has been removed in favour of Properties. Since RoomClient is no longer optional for using the Network Spawner, this parameter can be trivially replaced with peer == roomClient.Me (which was done in the samples even when origin was available!).

  1. SpawnWithRoomScope now returns an object that inherits from IEnumerator and allows a co-routine to suspend on it. The purpose is to allow a function to suspend until Room-scoped objects have been spawned on the Peer that created them.

This is not the recommended way to set instance properties, since there is still a race condition: this object may turn up on that Peer before it has finished Registering on others, so any message it sends immediately after it is created may still be lost. The way to initialise Prefabs is to use the Properties parameter above.

This functionality can be used to do Peer-local things however, such as immediately grasp the spawned object, or similar.

_06_SpawnerWithScope.cs has been updated with logic and comments to demonstrate both 2 & 3.

Behind the scenes:

  1. NetworkSpawner has been simplified, and fully leans into using the dictionaries and only the dictionaries. Instead of having similar control flows for Rooms and Peers there is now only one UpdateSpawned method, which uses an object instance as a token for the scope, and all spawned objects etc are maintained in dictionaries which use this as a key. At the moment, this is actually the Room or Peer object from RoomClient, since there are no more scopes! This makes it much easier to add more in the future however.

@bnco-dev, I have copied samples 04-08 into this branch. I tried to find a way that worked well with Git but couldn't, so there'll be a conflict unfortunately :(, but I have made sure the tree structure matches, and to copy the .meta files, so when this is pulled after the packaging updates, it should be safe to just override with the ones in this branch.