mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 02:50:32 +00:00
feat(NetworkServer): Improved ReplacePlayerForConnection (#3885)
- ReplacePlayerOptions: KeepAuthority, KeepActive, Unspawn, Destroy - NetworkServer tests updated - Examples updated and work correctly Eliminates need to make a coroutine to replace & destroy player.
This commit is contained in:
parent
46010ca49c
commit
d8c7c1e815
@ -146,7 +146,7 @@ void SceneLoadedForPlayer(NetworkConnectionToClient conn, GameObject roomPlayer)
|
||||
return;
|
||||
|
||||
// replace room player with game player
|
||||
NetworkServer.ReplacePlayerForConnection(conn, gamePlayer, true);
|
||||
NetworkServer.ReplacePlayerForConnection(conn, gamePlayer, ReplacePlayerOptions.KeepAuthority);
|
||||
}
|
||||
|
||||
internal void CallOnClientEnterRoom()
|
||||
@ -342,7 +342,7 @@ public override void ServerChangeScene(string newSceneName)
|
||||
{
|
||||
// re-add the room object
|
||||
roomPlayer.GetComponent<NetworkRoomPlayer>().readyToBegin = false;
|
||||
NetworkServer.ReplacePlayerForConnection(identity.connectionToClient, roomPlayer.gameObject);
|
||||
NetworkServer.ReplacePlayerForConnection(identity.connectionToClient, roomPlayer.gameObject, ReplacePlayerOptions.KeepAuthority);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,18 @@
|
||||
|
||||
namespace Mirror
|
||||
{
|
||||
public enum ReplacePlayerOptions
|
||||
{
|
||||
/// <summary>Player Object remains active on server and clients. Ownership is not removed</summary>
|
||||
KeepAuthority,
|
||||
/// <summary>Player Object remains active on server and clients. Only ownership is removed</summary>
|
||||
KeepActive,
|
||||
/// <summary>Player Object is unspawned on clients but remains on server</summary>
|
||||
Unspawn,
|
||||
/// <summary>Player Object is destroyed on server and clients</summary>
|
||||
Destroy
|
||||
}
|
||||
|
||||
public enum RemovePlayerOptions
|
||||
{
|
||||
/// <summary>Player Object remains active on server and clients. Only ownership is removed</summary>
|
||||
@ -1100,10 +1112,36 @@ public static bool AddPlayerForConnection(NetworkConnectionToClient conn, GameOb
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>Replaces connection's player object. The old object is not destroyed.</summary>
|
||||
// This does NOT change the ready state of the connection, so it can
|
||||
// safely be used while changing scenes.
|
||||
// Deprecated 2024-008-09
|
||||
[Obsolete("Use ReplacePlayerForConnection(NetworkConnectionToClient conn, GameObject player, uint assetId, ReplacePlayerOptions replacePlayerOptions) instead")]
|
||||
public static bool ReplacePlayerForConnection(NetworkConnectionToClient conn, GameObject player, uint assetId, bool keepAuthority = false)
|
||||
{
|
||||
if (GetNetworkIdentity(player, out NetworkIdentity identity))
|
||||
identity.assetId = assetId;
|
||||
|
||||
return ReplacePlayerForConnection(conn, player, keepAuthority ? ReplacePlayerOptions.KeepAuthority : ReplacePlayerOptions.KeepActive);
|
||||
}
|
||||
|
||||
// Deprecated 2024-008-09
|
||||
[Obsolete("Use ReplacePlayerForConnection(NetworkConnectionToClient conn, GameObject player, ReplacePlayerOptions replacePlayerOptions) instead")]
|
||||
public static bool ReplacePlayerForConnection(NetworkConnectionToClient conn, GameObject player, bool keepAuthority = false)
|
||||
{
|
||||
return ReplacePlayerForConnection(conn, player, keepAuthority ? ReplacePlayerOptions.KeepAuthority : ReplacePlayerOptions.KeepActive);
|
||||
}
|
||||
|
||||
/// <summary>Replaces connection's player object. The old object is not destroyed.</summary>
|
||||
// This does NOT change the ready state of the connection, so it can safely be used while changing scenes.
|
||||
public static bool ReplacePlayerForConnection(NetworkConnectionToClient conn, GameObject player, uint assetId, ReplacePlayerOptions replacePlayerOptions)
|
||||
{
|
||||
if (GetNetworkIdentity(player, out NetworkIdentity identity))
|
||||
identity.assetId = assetId;
|
||||
|
||||
return ReplacePlayerForConnection(conn, player, replacePlayerOptions);
|
||||
}
|
||||
|
||||
/// <summary>Replaces connection's player object. The old object is not destroyed.</summary>
|
||||
// This does NOT change the ready state of the connection, so it can safely be used while changing scenes.
|
||||
public static bool ReplacePlayerForConnection(NetworkConnectionToClient conn, GameObject player, ReplacePlayerOptions replacePlayerOptions)
|
||||
{
|
||||
if (!player.TryGetComponent(out NetworkIdentity identity))
|
||||
{
|
||||
@ -1145,33 +1183,28 @@ public static bool ReplacePlayerForConnection(NetworkConnectionToClient conn, Ga
|
||||
|
||||
Respawn(identity);
|
||||
|
||||
if (keepAuthority)
|
||||
switch (replacePlayerOptions)
|
||||
{
|
||||
// This needs to be sent to clear isLocalPlayer on
|
||||
// client while keeping hasAuthority true
|
||||
SendChangeOwnerMessage(previousPlayer, conn);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This clears both isLocalPlayer and hasAuthority on client
|
||||
previousPlayer.RemoveClientAuthority();
|
||||
case ReplacePlayerOptions.KeepAuthority:
|
||||
// This needs to be sent to clear isLocalPlayer on
|
||||
// client while keeping hasAuthority true
|
||||
SendChangeOwnerMessage(previousPlayer, conn);
|
||||
break;
|
||||
case ReplacePlayerOptions.KeepActive:
|
||||
// This clears both isLocalPlayer and hasAuthority on client
|
||||
previousPlayer.RemoveClientAuthority();
|
||||
break;
|
||||
case ReplacePlayerOptions.Unspawn:
|
||||
UnSpawn(previousPlayer.gameObject);
|
||||
break;
|
||||
case ReplacePlayerOptions.Destroy:
|
||||
Destroy(previousPlayer.gameObject);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>Replaces connection's player object. The old object is not destroyed.</summary>
|
||||
// This does NOT change the ready state of the connection, so it can
|
||||
// safely be used while changing scenes.
|
||||
public static bool ReplacePlayerForConnection(NetworkConnectionToClient conn, GameObject player, uint assetId, bool keepAuthority = false)
|
||||
{
|
||||
if (GetNetworkIdentity(player, out NetworkIdentity identity))
|
||||
{
|
||||
identity.assetId = assetId;
|
||||
}
|
||||
return ReplacePlayerForConnection(conn, player, keepAuthority);
|
||||
}
|
||||
|
||||
/// <summary>Removes the player object from the connection</summary>
|
||||
// destroyServerObject: Indicates whether the server object should be destroyed
|
||||
// Deprecated 2024-06-06
|
||||
|
@ -113,8 +113,7 @@ void OnReplaceCharacterMessage(NetworkConnectionToClient conn, ReplaceCharacterM
|
||||
GameObject playerObject = Instantiate(characterData.characterPrefabs[message.createCharacterMessage.characterNumber], oldPlayer.transform.position, oldPlayer.transform.rotation);
|
||||
|
||||
// Instantiate the new player object and broadcast to clients
|
||||
// Include true for keepAuthority paramater to prevent ownership change
|
||||
NetworkServer.ReplacePlayerForConnection(conn, playerObject, true);
|
||||
NetworkServer.ReplacePlayerForConnection(conn, playerObject, ReplacePlayerOptions.KeepActive);
|
||||
|
||||
// Apply data from the message however appropriate for your game
|
||||
// Typically Player would be a component you write with syncvars or properties
|
||||
|
@ -92,17 +92,7 @@ void CmdTakeControl(NetworkConnectionToClient conn = null)
|
||||
|
||||
isControlled = true;
|
||||
|
||||
// set the player object to be the tank, keep ownership of
|
||||
// the original player object to avoid ChangeOwner message.
|
||||
NetworkServer.ReplacePlayerForConnection(conn, gameObject);
|
||||
|
||||
StartCoroutine(UnspawnOldPlayer((GameObject)conn.authenticationData));
|
||||
}
|
||||
|
||||
IEnumerator UnspawnOldPlayer(GameObject player)
|
||||
{
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
NetworkServer.UnSpawn(player);
|
||||
NetworkServer.ReplacePlayerForConnection(conn, gameObject, ReplacePlayerOptions.Unspawn);
|
||||
}
|
||||
|
||||
[Command]
|
||||
@ -123,7 +113,7 @@ void CmdReleaseControl()
|
||||
// clear the player object
|
||||
connectionToClient.authenticationData = null;
|
||||
|
||||
NetworkServer.ReplacePlayerForConnection(connectionToClient, player);
|
||||
NetworkServer.ReplacePlayerForConnection(connectionToClient, player, ReplacePlayerOptions.KeepActive);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1342,7 +1342,7 @@ public void ReplacePlayerForConnection_CallsOnStartLocalPlayer()
|
||||
clientNextIdentity.name = nameof(clientNextIdentity);
|
||||
|
||||
// replace connection's player from 'previous' to 'next'
|
||||
NetworkServer.ReplacePlayerForConnection(connectionToClient, serverNextIdentity.gameObject);
|
||||
NetworkServer.ReplacePlayerForConnection(connectionToClient, serverNextIdentity.gameObject, ReplacePlayerOptions.KeepActive);
|
||||
ProcessMessages();
|
||||
|
||||
// should call OnStartLocalPlayer on 'next' since it became the new local player.
|
||||
@ -1372,7 +1372,7 @@ public void ReplacePlayerForConnection_CallsOnStopLocalPlayer()
|
||||
clientNextIdentity.name = nameof(clientNextIdentity);
|
||||
|
||||
// replace connection's player from 'previous' to 'next'
|
||||
NetworkServer.ReplacePlayerForConnection(connectionToClient, serverNextIdentity.gameObject);
|
||||
NetworkServer.ReplacePlayerForConnection(connectionToClient, serverNextIdentity.gameObject, ReplacePlayerOptions.KeepActive);
|
||||
ProcessMessages();
|
||||
|
||||
// should call OnStopLocalPlayer on 'previous' since it's not owned anymore now.
|
||||
|
Loading…
Reference in New Issue
Block a user