diff --git a/CHANGELOG.md b/CHANGELOG.md index 05d343cccc..319ebea3a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ - Schema components in ECS no longer have a `ComponentId` property. [#1308](https://github.com/spatialos/gdk-for-unity/pull/1308) - You should use `ComponentDatabase.GetComponentId()` instead. - `CustomSpatialOSSendSystem` is no longer available. [#1308](https://github.com/spatialos/gdk-for-unity/pull/1308) +- The Player Lifecycle feature module now provides an `EntityId` in its `CreatePlayerEntityTemplate` callback. [#1315](https://github.com/spatialos/gdk-for-unity/pull/1315) + - You will have to change your callback from `(string clientWorkerId, byte[] serializedArguments)` to `(EntityId entityId, string clientWorkerId, byte[] serializedArguments)`. ### Added diff --git a/UPGRADE_GUIDE.md b/UPGRADE_GUIDE.md index dde5d9e705..4a29ac49e0 100644 --- a/UPGRADE_GUIDE.md +++ b/UPGRADE_GUIDE.md @@ -1,5 +1,34 @@ # Upgrade Guide +## From `0.3.3` to `0.3.4` + +### PlayerLifecycle feature module now provides an EntityId + +The callback used for creating a player `EntityTemplate` has changed to provide an `EntityId` up front. +This player's Entity will have this `EntityId` after it is successfully spawned, and can be useful for defining QBI queries. + +For example: + +```csharp +public static EntityTemplate Player(string workerId, byte[] args) +{ + var template = new EntityTemplate(); + // ... + return template; +} +``` + +Would change into: + +```csharp +public static EntityTemplate Player(EntityId entityId, string workerId, byte[] args) +{ + var template = new EntityTemplate(); + // ... + return template; +} +``` + ## From `0.3.2` to `0.3.3` ### Building for Android now requires the NDK diff --git a/workers/unity/Assets/Playground/Config/PlayerTemplate.cs b/workers/unity/Assets/Playground/Config/PlayerTemplate.cs index b0c5aaf6d5..03b7127e82 100644 --- a/workers/unity/Assets/Playground/Config/PlayerTemplate.cs +++ b/workers/unity/Assets/Playground/Config/PlayerTemplate.cs @@ -9,7 +9,7 @@ namespace Playground { public static class PlayerTemplate { - public static EntityTemplate CreatePlayerEntityTemplate(string clientWorkerId, byte[] playerCreationArguments) + public static EntityTemplate CreatePlayerEntityTemplate(EntityId entityId, string clientWorkerId, byte[] playerCreationArguments) { var clientAttribute = EntityTemplate.GetWorkerAccessAttribute(clientWorkerId); diff --git a/workers/unity/Assets/Playground/Config/WorkerUtils.cs b/workers/unity/Assets/Playground/Config/WorkerUtils.cs index b4f96bd41a..1cbcc25978 100644 --- a/workers/unity/Assets/Playground/Config/WorkerUtils.cs +++ b/workers/unity/Assets/Playground/Config/WorkerUtils.cs @@ -36,7 +36,6 @@ public static void AddGameLogicSystems(World world) PlayerLifecycleHelper.AddServerSystems(world); GameObjectCreationHelper.EnableStandardGameObjectCreation(world); - world.GetOrCreateSystem(); world.GetOrCreateSystem(); world.GetOrCreateSystem(); world.GetOrCreateSystem(); diff --git a/workers/unity/Packages/io.improbable.gdk.playerlifecycle/Config/PlayerLifecycleConfig.cs b/workers/unity/Packages/io.improbable.gdk.playerlifecycle/Config/PlayerLifecycleConfig.cs index 99efd6ea81..1442dc726a 100644 --- a/workers/unity/Packages/io.improbable.gdk.playerlifecycle/Config/PlayerLifecycleConfig.cs +++ b/workers/unity/Packages/io.improbable.gdk.playerlifecycle/Config/PlayerLifecycleConfig.cs @@ -20,6 +20,7 @@ namespace Improbable.Gdk.PlayerLifecycle /// An to create a SpatialOS player entity from. /// public delegate EntityTemplate GetPlayerEntityTemplateDelegate( + EntityId entityId, string clientWorkerId, byte[] serializedArguments); diff --git a/workers/unity/Packages/io.improbable.gdk.playerlifecycle/PlayerLifecycleHelper.cs b/workers/unity/Packages/io.improbable.gdk.playerlifecycle/PlayerLifecycleHelper.cs index 0734b7774a..5c3f8b8cde 100644 --- a/workers/unity/Packages/io.improbable.gdk.playerlifecycle/PlayerLifecycleHelper.cs +++ b/workers/unity/Packages/io.improbable.gdk.playerlifecycle/PlayerLifecycleHelper.cs @@ -65,6 +65,7 @@ public static void AddClientSystems(World world, bool autoRequestPlayerCreation /// A world that belongs to a server-worker. public static void AddServerSystems(World world) { + world.GetOrCreateSystem(); world.GetOrCreateSystem(); world.GetOrCreateSystem(); world.GetOrCreateSystem(); diff --git a/workers/unity/Packages/io.improbable.gdk.playerlifecycle/Systems/PlayerCreation/HandleCreatePlayerRequestSystem.cs b/workers/unity/Packages/io.improbable.gdk.playerlifecycle/Systems/PlayerCreation/HandleCreatePlayerRequestSystem.cs index 8c0e06f1b2..a435dd65af 100644 --- a/workers/unity/Packages/io.improbable.gdk.playerlifecycle/Systems/PlayerCreation/HandleCreatePlayerRequestSystem.cs +++ b/workers/unity/Packages/io.improbable.gdk.playerlifecycle/Systems/PlayerCreation/HandleCreatePlayerRequestSystem.cs @@ -11,11 +11,13 @@ namespace Improbable.Gdk.PlayerLifecycle public class HandleCreatePlayerRequestSystem : ComponentSystem { private CommandSystem commandSystem; + private EntityReservationSystem entityReservationSystem; protected override void OnCreate() { base.OnCreate(); commandSystem = World.GetExistingSystem(); + entityReservationSystem = World.GetExistingSystem(); } private class PlayerCreationRequestContext @@ -40,24 +42,34 @@ private void HandlePlayerCreateRequests() for (var i = 0; i < requests.Count; ++i) { ref readonly var request = ref requests[i]; - var playerEntityTemplate = PlayerLifecycleConfig.CreatePlayerEntityTemplate( - request.CallerWorkerId, - request.Payload.SerializedArguments - ); - - var entityRequest = new WorldCommands.CreateEntity.Request - ( - playerEntityTemplate, - context: new PlayerCreationRequestContext - { - createPlayerRequest = request - } - ); - - commandSystem.SendCommand(entityRequest); + + SpawnPlayerEntity(request); } } + private async void SpawnPlayerEntity(PlayerCreator.CreatePlayer.ReceivedRequest receivedRequest) + { + var entityId = await entityReservationSystem.GetAsync(); + + var playerEntityTemplate = PlayerLifecycleConfig.CreatePlayerEntityTemplate( + entityId, + receivedRequest.CallerWorkerId, + receivedRequest.Payload.SerializedArguments + ); + + var entityRequest = new WorldCommands.CreateEntity.Request + ( + playerEntityTemplate, + entityId, + context: new PlayerCreationRequestContext + { + createPlayerRequest = receivedRequest + } + ); + + commandSystem.SendCommand(entityRequest); + } + private void HandlePlayerCreateEntityResponses() { var responses = commandSystem.GetResponses();