Skip to content

Commit

Permalink
fix: player spawn not applying position and rotation via connection a…
Browse files Browse the repository at this point in the history
…pproval (#3078)

* fix

Apply the position and rotation set by the NetworkManager.ConnectionApprovalResponse when connection approval is enabled and auto-spawn player prefabs is enabled.

* test

Validation test for this PR

* update

adding changelog entry
  • Loading branch information
NoelStephensUnity authored Sep 27, 2024
1 parent ef9e1c1 commit 390c332
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 5 deletions.
1 change: 1 addition & 0 deletions com.unity.netcode.gameobjects/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Additional documentation and release notes are available at [Multiplayer Documen

### Fixed

- Fixed issue where applying the position and/or rotation to the `NetworkManager.ConnectionApprovalResponse` when connection approval and auto-spawn player prefab were enabled would not apply the position and/or rotation when the player prefab was instantiated. (#3078)
- Fixed issue with the client count not being correct on the host or server side when a client disconnects itself from a session. (#3075)

### Changed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -752,8 +752,8 @@ internal NetworkObject GetNetworkObjectToSpawn(uint globalObjectIdHash, ulong ow
}
else
{
// Create prefab instance
networkObject = UnityEngine.Object.Instantiate(networkPrefabReference).GetComponent<NetworkObject>();
// Create prefab instance while applying any pre-assigned position and rotation values
networkObject = UnityEngine.Object.Instantiate(networkPrefabReference, position, rotation).GetComponent<NetworkObject>();
networkObject.NetworkManagerOwner = NetworkManager;
networkObject.PrefabGlobalObjectIdHash = globalObjectIdHash;
}
Expand Down
41 changes: 38 additions & 3 deletions com.unity.netcode.gameobjects/Tests/Runtime/ConnectionApproval.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Text;
using NUnit.Framework;
using Unity.Netcode.TestHelpers.Runtime;
using UnityEngine;
using UnityEngine.TestTools;

namespace Unity.Netcode.RuntimeTests
Expand All @@ -12,9 +13,10 @@ namespace Unity.Netcode.RuntimeTests
[TestFixture(PlayerCreation.PrefabHash)]
[TestFixture(PlayerCreation.NoPlayer)]
[TestFixture(PlayerCreation.FailValidation)]
internal class ConnectionApprovalTests : NetcodeIntegrationTest
internal class ConnectionApprovalTests : IntegrationTestWithApproximation
{
private const string k_InvalidToken = "Invalid validation token!";

public enum PlayerCreation
{
Prefab,
Expand All @@ -24,6 +26,8 @@ public enum PlayerCreation
}
private PlayerCreation m_PlayerCreation;
private bool m_ClientDisconnectReasonValidated;
private Vector3 m_ExpectedPosition;
private Quaternion m_ExpectedRotation;

private Dictionary<ulong, bool> m_Validated = new Dictionary<ulong, bool>();

Expand All @@ -43,6 +47,12 @@ protected override bool ShouldCheckForSpawnedPlayers()

protected override void OnServerAndClientsCreated()
{
if (m_PlayerCreation == PlayerCreation.Prefab || m_PlayerCreation == PlayerCreation.PrefabHash)
{
m_ExpectedPosition = GetRandomVector3(-10.0f, 10.0f);
m_ExpectedRotation = Quaternion.Euler(GetRandomVector3(-359.98f, 359.98f));
}

m_ClientDisconnectReasonValidated = false;
m_BypassConnectionTimeout = m_PlayerCreation == PlayerCreation.FailValidation;
m_Validated.Clear();
Expand Down Expand Up @@ -104,11 +114,36 @@ private bool ClientAndHostValidated()
return true;
}

private bool ValidatePlayersPositionRotation()
{
foreach (var playerEntries in m_PlayerNetworkObjects)
{
foreach (var player in playerEntries.Value)
{
if (!Approximately(player.Value.transform.position, m_ExpectedPosition))
{
return false;
}
if (!Approximately(player.Value.transform.rotation, m_ExpectedRotation))
{
return false;
}
}
}
return true;
}

[UnityTest]
public IEnumerator ConnectionApproval()
{
yield return WaitForConditionOrTimeOut(ClientAndHostValidated);
AssertOnTimeout("Timed out waiting for all clients to be approved!");

if (m_PlayerCreation == PlayerCreation.Prefab || m_PlayerCreation == PlayerCreation.PrefabHash)
{
yield return WaitForConditionOrTimeOut(ValidatePlayersPositionRotation);
AssertOnTimeout("Not all player prefabs spawned in the correct position and/or rotation!");
}
}

private void NetworkManagerObject_ConnectionApprovalCallback(NetworkManager.ConnectionApprovalRequest request, NetworkManager.ConnectionApprovalResponse response)
Expand All @@ -127,8 +162,8 @@ private void NetworkManagerObject_ConnectionApprovalCallback(NetworkManager.Conn
}

response.CreatePlayerObject = ShouldCheckForSpawnedPlayers();
response.Position = null;
response.Rotation = null;
response.Position = m_ExpectedPosition;
response.Rotation = m_ExpectedRotation;
response.PlayerPrefabHash = m_PlayerCreation == PlayerCreation.PrefabHash ? m_PlayerPrefab.GetComponent<NetworkObject>().GlobalObjectIdHash : null;
}

Expand Down

0 comments on commit 390c332

Please sign in to comment.