diff --git a/Mirror/Editor/NetworkIdentityEditor.cs b/Mirror/Editor/NetworkIdentityEditor.cs index 0e2da9459..2a54c8a69 100644 --- a/Mirror/Editor/NetworkIdentityEditor.cs +++ b/Mirror/Editor/NetworkIdentityEditor.cs @@ -80,21 +80,12 @@ public override void OnInspectorGUI() if (m_ShowObservers) { EditorGUI.indentLevel += 1; - foreach (var o in m_NetworkIdentity.observers) + foreach (NetworkConnection observer in m_NetworkIdentity.observers) { - GameObject obj = null; - foreach (var p in o.playerControllers) - { - if (p != null) - { - obj = p.gameObject; - break; - } - } - if (obj) - EditorGUILayout.ObjectField("Connection " + o.connectionId, obj, typeof(GameObject), false); + if (observer.playerController != null) + EditorGUILayout.ObjectField("Connection " + observer.connectionId, observer.playerController.gameObject, typeof(GameObject), false); else - EditorGUILayout.TextField("Connection " + o.connectionId); + EditorGUILayout.TextField("Connection " + observer.connectionId); } EditorGUI.indentLevel -= 1; } diff --git a/Mirror/Editor/NetworkInformationPreview.cs b/Mirror/Editor/NetworkInformationPreview.cs index c5a224887..6a55da9f1 100644 --- a/Mirror/Editor/NetworkInformationPreview.cs +++ b/Mirror/Editor/NetworkInformationPreview.cs @@ -231,8 +231,6 @@ void GetNetworkInformation(GameObject gameObject) m_Info.Add(GetString("Network ID", m_Identity.netId.ToString())); - m_Info.Add(GetString("Player Controller ID", m_Identity.playerControllerId.ToString())); - m_Info.Add(GetBoolean("Is Client", m_Identity.isClient)); m_Info.Add(GetBoolean("Is Server", m_Identity.isServer)); m_Info.Add(GetBoolean("Has Authority", m_Identity.hasAuthority)); diff --git a/Mirror/Editor/NetworkManagerHUDEditor.cs b/Mirror/Editor/NetworkManagerHUDEditor.cs index 583fa9aa5..2772cfdf2 100644 --- a/Mirror/Editor/NetworkManagerHUDEditor.cs +++ b/Mirror/Editor/NetworkManagerHUDEditor.cs @@ -120,10 +120,7 @@ void ShowServerConnections() if (m_ShowPlayersForConnections[index]) { EditorGUI.indentLevel += 1; - foreach (var player in con.playerControllers) - { - EditorGUILayout.ObjectField("Player: " + player.playerControllerId, player.gameObject, typeof(GameObject), true); - } + EditorGUILayout.ObjectField("Player: ", con.playerController.gameObject, typeof(GameObject), true); EditorGUI.indentLevel -= 1; } @@ -253,10 +250,7 @@ void ShowClientInfo() { EditorGUILayout.TextField("client " + count + ":" , cl.GetType().Name + " Conn: " + cl.connection); EditorGUI.indentLevel += 1; - foreach (var p in cl.connection.playerControllers) - { - EditorGUILayout.LabelField("Player", p.ToString()); - } + EditorGUILayout.LabelField("Player", cl.connection.playerController.name); EditorGUI.indentLevel -= 1; } count++; @@ -330,9 +324,9 @@ void ShowControls() { ClientScene.Ready(m_Manager.client.connection); - if (ClientScene.localPlayers.Count == 0) + if (ClientScene.localPlayer == null) { - ClientScene.AddPlayer(0); + ClientScene.AddPlayer(); } } } diff --git a/Mirror/Runtime/ClientScene.cs b/Mirror/Runtime/ClientScene.cs index 6558b6ca4..0ffdaf172 100644 --- a/Mirror/Runtime/ClientScene.cs +++ b/Mirror/Runtime/ClientScene.cs @@ -5,7 +5,7 @@ namespace Mirror { public class ClientScene { - static List s_LocalPlayers = new List(); + static NetworkIdentity s_LocalPlayer; static NetworkConnection s_ReadyConnection; static Dictionary s_SpawnableObjects; @@ -18,14 +18,9 @@ internal static void SetNotReady() s_IsReady = false; } - struct PendingOwner - { - public NetworkInstanceId netId; - public short playerControllerId; - } - static List s_PendingOwnerIds = new List(); + static List s_PendingOwnerIds = new List(); - public static List localPlayers { get { return s_LocalPlayers; } } + public static NetworkIdentity localPlayer { get { return s_LocalPlayer; } } public static bool ready { get { return s_IsReady; } } public static NetworkConnection readyConnection { get { return s_ReadyConnection; }} @@ -37,8 +32,7 @@ struct PendingOwner internal static void Shutdown() { s_NetworkScene.Shutdown(); - s_LocalPlayers = new List(); - s_PendingOwnerIds = new List(); + s_PendingOwnerIds = new List(); s_SpawnableObjects = null; s_ReadyConnection = null; s_IsReady = false; @@ -48,69 +42,38 @@ internal static void Shutdown() } // this is called from message handler for Owner message - internal static void InternalAddPlayer(NetworkIdentity view, short playerControllerId) + internal static void InternalAddPlayer(NetworkIdentity view) { - if (LogFilter.logDebug) { Debug.LogWarning("ClientScene::InternalAddPlayer: playerControllerId : " + playerControllerId); } - - if (playerControllerId >= s_LocalPlayers.Count) - { - if (LogFilter.logWarn) { Debug.LogWarning("ClientScene::InternalAddPlayer: playerControllerId higher than expected: " + playerControllerId); } - while (playerControllerId >= s_LocalPlayers.Count) - { - s_LocalPlayers.Add(new PlayerController()); - } - } + if (LogFilter.logDebug) { Debug.LogWarning("ClientScene::InternalAddPlayer"); } // NOTE: It can be "normal" when changing scenes for the player to be destroyed and recreated. // But, the player structures are not cleaned up, we'll just replace the old player - var newPlayer = new PlayerController {gameObject = view.gameObject, playerControllerId = playerControllerId, unetView = view}; - s_LocalPlayers[playerControllerId] = newPlayer; + s_LocalPlayer = view; if (s_ReadyConnection == null) { if (LogFilter.logWarn) { Debug.LogWarning("No ready connection found for setting player controller during InternalAddPlayer"); } } else { - s_ReadyConnection.SetPlayerController(newPlayer); + s_ReadyConnection.SetPlayerController(view); } } // use this if already ready - public static bool AddPlayer(short playerControllerId) + public static bool AddPlayer() { - return AddPlayer(null, playerControllerId); + return AddPlayer(null); } // use this to implicitly become ready - public static bool AddPlayer(NetworkConnection readyConn, short playerControllerId) + public static bool AddPlayer(NetworkConnection readyConn) { - return AddPlayer(readyConn, playerControllerId, null); + return AddPlayer(readyConn, null); } // use this to implicitly become ready - public static bool AddPlayer(NetworkConnection readyConn, short playerControllerId, MessageBase extraMessage) + public static bool AddPlayer(NetworkConnection readyConn, MessageBase extraMessage) { - if (playerControllerId < 0) - { - if (LogFilter.logError) { Debug.LogError("ClientScene::AddPlayer: playerControllerId of " + playerControllerId + " is negative"); } - return false; - } - if (playerControllerId > PlayerController.MaxPlayersPerClient) - { - if (LogFilter.logError) { Debug.LogError("ClientScene::AddPlayer: playerControllerId of " + playerControllerId + " is too high, max is " + PlayerController.MaxPlayersPerClient); } - return false; - } - if (playerControllerId > PlayerController.MaxPlayersPerClient / 2) - { - if (LogFilter.logWarn) { Debug.LogWarning("ClientScene::AddPlayer: playerControllerId of " + playerControllerId + " is unusually high"); } - } - - // fill out local players array - while (playerControllerId >= s_LocalPlayers.Count) - { - s_LocalPlayers.Add(new PlayerController()); - } - // ensure valid ready connection if (readyConn != null) { @@ -124,23 +87,18 @@ public static bool AddPlayer(NetworkConnection readyConn, short playerController return false; } - PlayerController existingPlayerController; - if (s_ReadyConnection.GetPlayerController(playerControllerId, out existingPlayerController)) + if (s_ReadyConnection.playerController != null) { - if (existingPlayerController.IsValid && existingPlayerController.gameObject != null) - { - if (LogFilter.logError) { Debug.LogError("ClientScene::AddPlayer: playerControllerId of " + playerControllerId + " already in use."); } - return false; - } + if (LogFilter.logError) { Debug.LogError("ClientScene::AddPlayer: a PlayerController was already added. Did you call AddPlayer twice?"); } + return false; } - if (LogFilter.logDebug) { Debug.Log("ClientScene::AddPlayer() for ID " + playerControllerId + " called with connection [" + s_ReadyConnection + "]"); } + if (LogFilter.logDebug) { Debug.Log("ClientScene::AddPlayer() called with connection [" + s_ReadyConnection + "]"); } - var msg = new AddPlayerMessage(); - msg.playerControllerId = playerControllerId; + AddPlayerMessage msg = new AddPlayerMessage(); if (extraMessage != null) { - var writer = new NetworkWriter(); + NetworkWriter writer = new NetworkWriter(); extraMessage.Serialize(writer); msg.msgData = writer.ToArray(); } @@ -148,24 +106,21 @@ public static bool AddPlayer(NetworkConnection readyConn, short playerController return true; } - public static bool RemovePlayer(short playerControllerId) + public static bool RemovePlayer() { - if (LogFilter.logDebug) { Debug.Log("ClientScene::RemovePlayer() for ID " + playerControllerId + " called with connection [" + s_ReadyConnection + "]"); } + if (LogFilter.logDebug) { Debug.Log("ClientScene::RemovePlayer() called with connection [" + s_ReadyConnection + "]"); } - PlayerController playerController; - if (s_ReadyConnection.GetPlayerController(playerControllerId, out playerController)) + if (s_ReadyConnection.playerController != null) { - var msg = new RemovePlayerMessage(); - msg.playerControllerId = playerControllerId; + RemovePlayerMessage msg = new RemovePlayerMessage(); s_ReadyConnection.Send((short)MsgType.RemovePlayer, msg); - s_ReadyConnection.RemovePlayerController(playerControllerId); - s_LocalPlayers[playerControllerId] = new PlayerController(); + s_ReadyConnection.RemovePlayerController(); + s_LocalPlayer = null; - Object.Destroy(playerController.gameObject); + Object.Destroy(s_ReadyConnection.playerController.gameObject); return true; } - if (LogFilter.logError) { Debug.LogError("Failed to find player ID " + playerControllerId); } return false; } @@ -669,10 +624,9 @@ static void OnOwnerMessage(NetworkMessage netMsg) // is there already an owner that is a different object?? - PlayerController oldOwner; - if (netMsg.conn.GetPlayerController(msg.playerControllerId, out oldOwner)) + if (netMsg.conn.playerController != null) { - oldOwner.unetView.SetNotLocalPlayer(); + netMsg.conn.playerController.SetNotLocalPlayer(); } NetworkIdentity localNetworkIdentity; @@ -680,13 +634,12 @@ static void OnOwnerMessage(NetworkMessage netMsg) { // this object already exists localNetworkIdentity.SetConnectionToServer(netMsg.conn); - localNetworkIdentity.SetLocalPlayer(msg.playerControllerId); - InternalAddPlayer(localNetworkIdentity, msg.playerControllerId); + localNetworkIdentity.SetLocalPlayer(); + InternalAddPlayer(localNetworkIdentity); } else { - var pendingOwner = new PendingOwner { netId = msg.netId, playerControllerId = msg.playerControllerId }; - s_PendingOwnerIds.Add(pendingOwner); + s_PendingOwnerIds.Add(msg.netId); } } @@ -694,15 +647,15 @@ static void CheckForOwner(NetworkIdentity uv) { for (int i = 0; i < s_PendingOwnerIds.Count; i++) { - var pendingOwner = s_PendingOwnerIds[i]; + NetworkInstanceId pendingOwner = s_PendingOwnerIds[i]; - if (pendingOwner.netId == uv.netId) + if (pendingOwner == uv.netId) { // found owner, turn into a local player // Set isLocalPlayer to true on this NetworkIdentity and trigger OnStartLocalPlayer in all scripts on the same GO uv.SetConnectionToServer(s_ReadyConnection); - uv.SetLocalPlayer(pendingOwner.playerControllerId); + uv.SetLocalPlayer(); if (LogFilter.logDev) { Debug.Log("ClientScene::OnOwnerMessage - player=" + uv.gameObject.name); } if (s_ReadyConnection.connectionId < 0) @@ -710,7 +663,7 @@ static void CheckForOwner(NetworkIdentity uv) if (LogFilter.logError) { Debug.LogError("Owner message received on a local client."); } return; } - InternalAddPlayer(uv, pendingOwner.playerControllerId); + InternalAddPlayer(uv); s_PendingOwnerIds.RemoveAt(i); break; diff --git a/Mirror/Runtime/LocalClient.cs b/Mirror/Runtime/LocalClient.cs index 9c5c8363a..e86b9ce0d 100644 --- a/Mirror/Runtime/LocalClient.cs +++ b/Mirror/Runtime/LocalClient.cs @@ -52,19 +52,19 @@ internal override void Update() } // Called by the server to set the LocalClient's LocalPlayer object during NetworkServer.AddPlayer() - internal void AddLocalPlayer(PlayerController localPlayer) + internal void AddLocalPlayer(NetworkIdentity localPlayer) { if (LogFilter.logDev) Debug.Log("Local client AddLocalPlayer " + localPlayer.gameObject.name + " conn=" + m_Connection.connectionId); m_Connection.isReady = true; m_Connection.SetPlayerController(localPlayer); - var uv = localPlayer.unetView; + NetworkIdentity uv = localPlayer; if (uv != null) { ClientScene.SetLocalObject(uv.netId, localPlayer.gameObject); uv.SetConnectionToServer(m_Connection); } // there is no SystemOwnerMessage for local client. add to ClientScene here instead - ClientScene.InternalAddPlayer(uv, localPlayer.playerControllerId); + ClientScene.InternalAddPlayer(uv); } private void PostInternalMessage(short msgType, byte[] content) diff --git a/Mirror/Runtime/Messages.cs b/Mirror/Runtime/Messages.cs index 339e951d2..099e33c14 100644 --- a/Mirror/Runtime/Messages.cs +++ b/Mirror/Runtime/Messages.cs @@ -103,35 +103,21 @@ public class NotReadyMessage : EmptyMessage public class AddPlayerMessage : MessageBase { - public short playerControllerId; public byte[] msgData; public override void Deserialize(NetworkReader reader) { - playerControllerId = (short)reader.ReadPackedUInt32(); msgData = reader.ReadBytesAndSize(); } public override void Serialize(NetworkWriter writer) { - writer.WritePackedUInt32((uint)playerControllerId); writer.WriteBytesAndSize(msgData); } } public class RemovePlayerMessage : MessageBase { - public short playerControllerId; - - public override void Deserialize(NetworkReader reader) - { - playerControllerId = (short)reader.ReadPackedUInt32(); - } - - public override void Serialize(NetworkWriter writer) - { - writer.WritePackedUInt32((uint)playerControllerId); - } } // ---------- System Messages requried for code gen path ------------------- @@ -317,18 +303,15 @@ public override void Serialize(NetworkWriter writer) class OwnerMessage : MessageBase { public NetworkInstanceId netId; - public short playerControllerId; public override void Deserialize(NetworkReader reader) { netId = reader.ReadNetworkId(); - playerControllerId = (short)reader.ReadPackedUInt32(); } public override void Serialize(NetworkWriter writer) { writer.Write(netId); - writer.WritePackedUInt32((uint)playerControllerId); } } diff --git a/Mirror/Runtime/Mirror.Runtime.csproj b/Mirror/Runtime/Mirror.Runtime.csproj index 54234a8dd..c824367b9 100644 --- a/Mirror/Runtime/Mirror.Runtime.csproj +++ b/Mirror/Runtime/Mirror.Runtime.csproj @@ -78,7 +78,6 @@ - diff --git a/Mirror/Runtime/NetworkBehaviour.cs b/Mirror/Runtime/NetworkBehaviour.cs index b1d701a43..ee9fc6a94 100644 --- a/Mirror/Runtime/NetworkBehaviour.cs +++ b/Mirror/Runtime/NetworkBehaviour.cs @@ -23,7 +23,6 @@ public class NetworkBehaviour : MonoBehaviour public NetworkInstanceId netId { get { return myView.netId; } } public NetworkConnection connectionToServer { get { return myView.connectionToServer; } } public NetworkConnection connectionToClient { get { return myView.connectionToClient; } } - public short playerControllerId { get { return myView.playerControllerId; } } protected ulong syncVarDirtyBits { get { return m_SyncVarDirtyBits; } } protected bool syncVarHookGuard { get { return m_SyncVarGuard; } set { m_SyncVarGuard = value; }} diff --git a/Mirror/Runtime/NetworkConnection.cs b/Mirror/Runtime/NetworkConnection.cs index 4492087aa..e23bc3ecd 100644 --- a/Mirror/Runtime/NetworkConnection.cs +++ b/Mirror/Runtime/NetworkConnection.cs @@ -12,7 +12,7 @@ namespace Mirror */ public class NetworkConnection : IDisposable { - List m_PlayerControllers = new List(); + NetworkIdentity m_PlayerController; HashSet m_VisList = new HashSet(); public HashSet visList { get { return m_VisList; } } @@ -25,7 +25,7 @@ public class NetworkConnection : IDisposable public bool isReady; public string address; public float lastMessageTime; - public List playerControllers { get { return m_PlayerControllers; } } + public NetworkIdentity playerController { get { return m_PlayerController; } } public HashSet clientOwnedObjects { get { return m_ClientOwnedObjects; } } public bool logNetworkMessages = false; public bool isConnected { get { return hostId != -1; }} @@ -148,36 +148,14 @@ public void UnregisterHandler(short msgType) m_MessageHandlers.Remove(msgType); } - internal void SetPlayerController(PlayerController player) + internal void SetPlayerController(NetworkIdentity player) { - while (player.playerControllerId >= m_PlayerControllers.Count) - { - m_PlayerControllers.Add(new PlayerController()); - } - - m_PlayerControllers[player.playerControllerId] = player; + m_PlayerController = player; } - internal void RemovePlayerController(short playerControllerId) + internal void RemovePlayerController() { - int count = m_PlayerControllers.Count; - while (count >= 0) - { - if (playerControllerId == count && playerControllerId == m_PlayerControllers[count].playerControllerId) - { - m_PlayerControllers[count] = new PlayerController(); - return; - } - count -= 1; - } - if (LogFilter.logError) { Debug.LogError("RemovePlayer player at playerControllerId " + playerControllerId + " not found"); } - } - - // Get player controller from connection's list - internal bool GetPlayerController(short playerControllerId, out PlayerController playerController) - { - playerController = playerControllers.Find(pc => pc.IsValid && pc.playerControllerId == playerControllerId); - return playerController != null; + m_PlayerController = null; } public virtual bool Send(short msgType, MessageBase msg) diff --git a/Mirror/Runtime/NetworkIdentity.cs b/Mirror/Runtime/NetworkIdentity.cs index 38b88209b..e28142336 100644 --- a/Mirror/Runtime/NetworkIdentity.cs +++ b/Mirror/Runtime/NetworkIdentity.cs @@ -30,7 +30,6 @@ public sealed class NetworkIdentity : MonoBehaviour bool m_IsLocalPlayer; NetworkConnection m_ConnectionToServer; NetworkConnection m_ConnectionToClient; - short m_PlayerId = -1; NetworkBehaviour[] m_NetworkBehaviours; // there is a list AND a hashSet of connections, for fast verification of dupes, but the main operation is iteration over the list. @@ -112,7 +111,6 @@ internal void ForceAuthority(bool authority) } public bool isLocalPlayer { get { return m_IsLocalPlayer; } } - public short playerControllerId { get { return m_PlayerId; } } public NetworkConnection connectionToServer { get { return m_ConnectionToServer; } } public NetworkConnection connectionToClient { get { return m_ConnectionToClient; } } @@ -749,10 +747,9 @@ internal void OnUpdateVars(NetworkReader reader, bool initialState) OnDeserializeAllSafely(m_NetworkBehaviours, reader, initialState); } - internal void SetLocalPlayer(short localPlayerControllerId) + internal void SetLocalPlayer() { m_IsLocalPlayer = true; - m_PlayerId = localPlayerControllerId; // there is an ordering issue here that originAuthority solves. OnStartAuthority should only be called if m_HasAuthority was false when this function began, // or it will be called twice for this object. But that state is lost by the time OnStartAuthority is called below, so the original value is cached @@ -780,9 +777,8 @@ internal void SetConnectionToServer(NetworkConnection conn) m_ConnectionToServer = conn; } - internal void SetConnectionToClient(NetworkConnection conn, short newPlayerControllerId) + internal void SetConnectionToClient(NetworkConnection conn) { - m_PlayerId = newPlayerControllerId; m_ConnectionToClient = conn; } @@ -1049,7 +1045,6 @@ internal void Reset() m_IsLocalPlayer = false; m_ConnectionToServer = null; m_ConnectionToClient = null; - m_PlayerId = -1; m_NetworkBehaviours = null; ClearObservers(); diff --git a/Mirror/Runtime/NetworkManager.cs b/Mirror/Runtime/NetworkManager.cs index 1b0dd580f..36bd6797c 100644 --- a/Mirror/Runtime/NetworkManager.cs +++ b/Mirror/Runtime/NetworkManager.cs @@ -60,21 +60,7 @@ public class NetworkManager : MonoBehaviour public bool clientLoadedScene { get { return m_ClientLoadedScene; } set { m_ClientLoadedScene = value; } } // only really valid on the server - public int numPlayers - { - get - { - int amount = 0; - foreach (NetworkConnection conn in NetworkServer.connections) - { - if (conn != null) - { - amount += conn.playerControllers.Count(pc => pc.IsValid); - } - } - return amount; - } - } + public int numPlayers { get { return NetworkServer.connections.Count(conn => conn.playerController != null); } } // runtime data public static string networkSceneName = ""; // this is used to make sure that all scene changes are initialized by UNET. loading a scene manually wont set networkSceneName, so UNET would still load it again on start. @@ -579,12 +565,12 @@ internal void OnServerAddPlayerMessageInternal(NetworkMessage netMsg) if (msg.msgData != null && msg.msgData.Length > 0) { - var reader = new NetworkReader(msg.msgData); - OnServerAddPlayer(netMsg.conn, msg.playerControllerId, reader); + NetworkReader reader = new NetworkReader(msg.msgData); + OnServerAddPlayer(netMsg.conn, reader); } else { - OnServerAddPlayer(netMsg.conn, msg.playerControllerId); + OnServerAddPlayer(netMsg.conn); } } @@ -595,10 +581,11 @@ internal void OnServerRemovePlayerMessageInternal(NetworkMessage netMsg) RemovePlayerMessage msg = new RemovePlayerMessage(); netMsg.ReadMessage(msg); - PlayerController player; - netMsg.conn.GetPlayerController(msg.playerControllerId, out player); - OnServerRemovePlayer(netMsg.conn, player); - netMsg.conn.RemovePlayerController(msg.playerControllerId); + if (netMsg.conn.playerController != null) + { + OnServerRemovePlayer(netMsg.conn, netMsg.conn.playerController); + netMsg.conn.RemovePlayerController(); + } } internal void OnServerErrorInternal(NetworkMessage netMsg) @@ -680,13 +667,13 @@ public virtual void OnServerConnect(NetworkConnection conn) public virtual void OnServerDisconnect(NetworkConnection conn) { - NetworkServer.DestroyPlayersForConnection(conn); + NetworkServer.DestroyPlayerForConnection(conn); if (LogFilter.logDebug) { Debug.Log("OnServerDisconnect: Client disconnected."); } } public virtual void OnServerReady(NetworkConnection conn) { - if (conn.playerControllers.Count == 0) + if (conn.playerController == null) { // this is now allowed (was not for a while) if (LogFilter.logDebug) { Debug.Log("Ready with no player object"); } @@ -694,17 +681,17 @@ public virtual void OnServerReady(NetworkConnection conn) NetworkServer.SetClientReady(conn); } - public virtual void OnServerAddPlayer(NetworkConnection conn, short playerControllerId, NetworkReader extraMessageReader) + public virtual void OnServerAddPlayer(NetworkConnection conn, NetworkReader extraMessageReader) { - OnServerAddPlayerInternal(conn, playerControllerId); + OnServerAddPlayerInternal(conn); } - public virtual void OnServerAddPlayer(NetworkConnection conn, short playerControllerId) + public virtual void OnServerAddPlayer(NetworkConnection conn) { - OnServerAddPlayerInternal(conn, playerControllerId); + OnServerAddPlayerInternal(conn); } - void OnServerAddPlayerInternal(NetworkConnection conn, short playerControllerId) + void OnServerAddPlayerInternal(NetworkConnection conn) { if (m_PlayerPrefab == null) { @@ -718,9 +705,9 @@ void OnServerAddPlayerInternal(NetworkConnection conn, short playerControllerId) return; } - if (playerControllerId < conn.playerControllers.Count && conn.playerControllers[playerControllerId].IsValid && conn.playerControllers[playerControllerId].gameObject != null) + if (conn.playerController != null) { - if (LogFilter.logError) { Debug.LogError("There is already a player at that playerControllerId for this connections."); } + if (LogFilter.logError) { Debug.LogError("There is already a player for this connections."); } return; } @@ -735,7 +722,7 @@ void OnServerAddPlayerInternal(NetworkConnection conn, short playerControllerId) player = Instantiate(m_PlayerPrefab, Vector3.zero, Quaternion.identity); } - NetworkServer.AddPlayerForConnection(conn, player, playerControllerId); + NetworkServer.AddPlayerForConnection(conn, player); } public Transform GetStartPosition() @@ -763,7 +750,7 @@ public Transform GetStartPosition() return null; } - public virtual void OnServerRemovePlayer(NetworkConnection conn, PlayerController player) + public virtual void OnServerRemovePlayer(NetworkConnection conn, NetworkIdentity player) { if (player.gameObject != null) { @@ -789,7 +776,7 @@ public virtual void OnClientConnect(NetworkConnection conn) ClientScene.Ready(conn); if (m_AutoCreatePlayer) { - ClientScene.AddPlayer(0); + ClientScene.AddPlayer(); } } } @@ -815,10 +802,10 @@ public virtual void OnClientSceneChanged(NetworkConnection conn) // vis2k: replaced all this weird code with something more simple if (m_AutoCreatePlayer) { - // add player if all existing ones are null (or if list is empty, then .All returns true) - if (ClientScene.localPlayers.All(pc => pc.gameObject == null)) + // add player if existing one is null + if (ClientScene.localPlayer == null) { - ClientScene.AddPlayer(0); + ClientScene.AddPlayer(); } } } diff --git a/Mirror/Runtime/NetworkManagerHUD.cs b/Mirror/Runtime/NetworkManagerHUD.cs index de796a0c5..fda806db0 100644 --- a/Mirror/Runtime/NetworkManagerHUD.cs +++ b/Mirror/Runtime/NetworkManagerHUD.cs @@ -99,9 +99,9 @@ void OnGUI() { ClientScene.Ready(manager.client.connection); - if (ClientScene.localPlayers.Count == 0) + if (ClientScene.localPlayer == null) { - ClientScene.AddPlayer(0); + ClientScene.AddPlayer(); } } } diff --git a/Mirror/Runtime/NetworkProximityChecker.cs b/Mirror/Runtime/NetworkProximityChecker.cs index 5f67ba383..d5312796b 100644 --- a/Mirror/Runtime/NetworkProximityChecker.cs +++ b/Mirror/Runtime/NetworkProximityChecker.cs @@ -46,14 +46,9 @@ public override bool OnCheckObserver(NetworkConnection newObserver) if (forceHidden) return false; - // this cant use newObserver.playerControllers[0]. must iterate to find a valid player. - PlayerController controller = newObserver.playerControllers.Find( - pc => pc != null && pc.gameObject != null - ); - if (controller != null) + if (newObserver.playerController != null) { - GameObject player = controller.gameObject; - return Vector3.Distance(player.transform.position, transform.position) < visRange; + return Vector3.Distance(newObserver.playerController.transform.position, transform.position) < visRange; } return false; } diff --git a/Mirror/Runtime/NetworkServer.cs b/Mirror/Runtime/NetworkServer.cs index e3db7d14e..8f0501e2e 100644 --- a/Mirror/Runtime/NetworkServer.cs +++ b/Mirror/Runtime/NetworkServer.cs @@ -441,7 +441,7 @@ static void OnDisconnected(NetworkConnection conn) { conn.InvokeHandlerNoData((short)MsgType.Disconnect); - if (conn.playerControllers.Any(pc => pc.gameObject != null)) + if (conn.playerController != null) { //NOTE: should there be default behaviour here to destroy the associated player? if (LogFilter.logWarn) { Debug.LogWarning("Player not destroyed when connection disconnected."); } @@ -555,17 +555,13 @@ public static void SendToClientOfPlayer(GameObject player, short msgType, Messag { for (int i = 0; i < connections.Count; i++) { - var conn = connections[i]; - if (conn != null) + NetworkConnection conn = connections[i]; + if (conn != null && + conn.playerController != null && + conn.playerController.gameObject == player) { - for (int j = 0; j < conn.playerControllers.Count; j++) - { - if (conn.playerControllers[j].IsValid && conn.playerControllers[j].gameObject == player) - { - conn.Send(msgType, msg); - return; - } - } + conn.Send(msgType, msg); + return; } } @@ -586,37 +582,37 @@ public static void SendToClient(int connectionId, short msgType, MessageBase msg if (LogFilter.logError) { Debug.LogError("Failed to send message to connection ID '" + connectionId + ", not found in connection list"); } } - public static bool ReplacePlayerForConnection(NetworkConnection conn, GameObject player, short playerControllerId, NetworkHash128 assetId) + public static bool ReplacePlayerForConnection(NetworkConnection conn, GameObject player, NetworkHash128 assetId) { NetworkIdentity id; if (GetNetworkIdentity(player, out id)) { id.SetDynamicAssetId(assetId); } - return InternalReplacePlayerForConnection(conn, player, playerControllerId); + return InternalReplacePlayerForConnection(conn, player); } - public static bool ReplacePlayerForConnection(NetworkConnection conn, GameObject player, short playerControllerId) + public static bool ReplacePlayerForConnection(NetworkConnection conn, GameObject player) { - return InternalReplacePlayerForConnection(conn, player, playerControllerId); + return InternalReplacePlayerForConnection(conn, player); } - public static bool AddPlayerForConnection(NetworkConnection conn, GameObject player, short playerControllerId, NetworkHash128 assetId) + public static bool AddPlayerForConnection(NetworkConnection conn, GameObject player, NetworkHash128 assetId) { NetworkIdentity id; if (GetNetworkIdentity(player, out id)) { id.SetDynamicAssetId(assetId); } - return InternalAddPlayerForConnection(conn, player, playerControllerId); + return InternalAddPlayerForConnection(conn, player); } - public static bool AddPlayerForConnection(NetworkConnection conn, GameObject player, short playerControllerId) + public static bool AddPlayerForConnection(NetworkConnection conn, GameObject player) { - return InternalAddPlayerForConnection(conn, player, playerControllerId); + return InternalAddPlayerForConnection(conn, player); } - internal static bool InternalAddPlayerForConnection(NetworkConnection conn, GameObject playerGameObject, short playerControllerId) + internal static bool InternalAddPlayerForConnection(NetworkConnection conn, GameObject playerGameObject) { NetworkIdentity playerNetworkIdentity; if (!GetNetworkIdentity(playerGameObject, out playerNetworkIdentity)) @@ -626,31 +622,21 @@ internal static bool InternalAddPlayerForConnection(NetworkConnection conn, Game } playerNetworkIdentity.Reset(); - if (!CheckPlayerControllerIdForConnection(conn, playerControllerId)) - return false; - // cannot have a player object in "Add" version - PlayerController oldController = null; - GameObject oldPlayer = null; - if (conn.GetPlayerController(playerControllerId, out oldController)) + if (conn.playerController != null) { - oldPlayer = oldController.gameObject; - } - if (oldPlayer != null) - { - if (LogFilter.logError) { Debug.Log("AddPlayer: player object already exists for playerControllerId of " + playerControllerId); } + if (LogFilter.logError) { Debug.Log("AddPlayer: player object already exists"); } return false; } - PlayerController newPlayerController = new PlayerController(playerGameObject, playerControllerId); - conn.SetPlayerController(newPlayerController); + conn.SetPlayerController(playerNetworkIdentity); - // Set the playerControllerId on the NetworkIdentity on the server, NetworkIdentity.SetLocalPlayer is not called on the server (it is on clients and that sets the playerControllerId there) - playerNetworkIdentity.SetConnectionToClient(conn, newPlayerController.playerControllerId); + // Set the connection on the NetworkIdentity on the server, NetworkIdentity.SetLocalPlayer is not called on the server (it is on clients) + playerNetworkIdentity.SetConnectionToClient(conn); SetClientReady(conn); - if (SetupLocalPlayerForConnection(conn, playerNetworkIdentity, newPlayerController)) + if (SetupLocalPlayerForConnection(conn, playerNetworkIdentity)) { return true; } @@ -665,26 +651,7 @@ internal static bool InternalAddPlayerForConnection(NetworkConnection conn, Game return true; } - static bool CheckPlayerControllerIdForConnection(NetworkConnection conn, short playerControllerId) - { - if (playerControllerId < 0) - { - if (LogFilter.logError) { Debug.LogError("AddPlayer: playerControllerId of " + playerControllerId + " is negative"); } - return false; - } - if (playerControllerId > PlayerController.MaxPlayersPerClient) - { - if (LogFilter.logError) { Debug.Log("AddPlayer: playerControllerId of " + playerControllerId + " is too high. max is " + PlayerController.MaxPlayersPerClient); } - return false; - } - if (playerControllerId > PlayerController.MaxPlayersPerClient / 2) - { - if (LogFilter.logWarn) { Debug.LogWarning("AddPlayer: playerControllerId of " + playerControllerId + " is unusually high"); } - } - return true; - } - - static bool SetupLocalPlayerForConnection(NetworkConnection conn, NetworkIdentity uv, PlayerController newPlayerController) + static bool SetupLocalPlayerForConnection(NetworkConnection conn, NetworkIdentity uv) { if (LogFilter.logDev) { Debug.Log("NetworkServer SetupLocalPlayerForConnection netID:" + uv.netId); } @@ -704,14 +671,14 @@ static bool SetupLocalPlayerForConnection(NetworkConnection conn, NetworkIdentit SendSpawnMessage(uv, null); // Set up local player instance on the client instance and update local object map - localConnection.localClient.AddLocalPlayer(newPlayerController); + localConnection.localClient.AddLocalPlayer(uv); uv.SetClientOwner(conn); // Trigger OnAuthority uv.ForceAuthority(true); // Trigger OnStartLocalPlayer - uv.SetLocalPlayer(newPlayerController.playerControllerId); + uv.SetLocalPlayer(); return true; } return false; @@ -728,11 +695,10 @@ static void FinishPlayerForConnection(NetworkConnection conn, NetworkIdentity uv OwnerMessage owner = new OwnerMessage(); owner.netId = uv.netId; - owner.playerControllerId = uv.playerControllerId; conn.Send((short)MsgType.Owner, owner); } - internal static bool InternalReplacePlayerForConnection(NetworkConnection conn, GameObject playerGameObject, short playerControllerId) + internal static bool InternalReplacePlayerForConnection(NetworkConnection conn, GameObject playerGameObject) { NetworkIdentity playerNetworkIdentity; if (!GetNetworkIdentity(playerGameObject, out playerNetworkIdentity)) @@ -741,31 +707,26 @@ internal static bool InternalReplacePlayerForConnection(NetworkConnection conn, return false; } - if (!CheckPlayerControllerIdForConnection(conn, playerControllerId)) - return false; - //NOTE: there can be an existing player if (LogFilter.logDev) { Debug.Log("NetworkServer ReplacePlayer"); } // is there already an owner that is a different object?? - PlayerController oldOwner; - if (conn.GetPlayerController(playerControllerId, out oldOwner)) + if (conn.playerController != null) { - oldOwner.unetView.SetNotLocalPlayer(); - oldOwner.unetView.ClearClientOwner(); + conn.playerController.SetNotLocalPlayer(); + conn.playerController.ClearClientOwner(); } - PlayerController newPlayerController = new PlayerController(playerGameObject, playerControllerId); - conn.SetPlayerController(newPlayerController); + conn.SetPlayerController(playerNetworkIdentity); - // Set the playerControllerId on the NetworkIdentity on the server, NetworkIdentity.SetLocalPlayer is not called on the server (it is on clients and that sets the playerControllerId there) - playerNetworkIdentity.SetConnectionToClient(conn, newPlayerController.playerControllerId); + // Set the connection on the NetworkIdentity on the server, NetworkIdentity.SetLocalPlayer is not called on the server (it is on clients) + playerNetworkIdentity.SetConnectionToClient(conn); //NOTE: DONT set connection ready. if (LogFilter.logDev) { Debug.Log("NetworkServer ReplacePlayer setup local"); } - if (SetupLocalPlayerForConnection(conn, playerNetworkIdentity, newPlayerController)) + if (SetupLocalPlayerForConnection(conn, playerNetworkIdentity)) { return true; } @@ -806,7 +767,7 @@ internal static void SetClientReadyInternal(NetworkConnection conn) return; } - if (conn.playerControllers.Count == 0) + if (conn.playerController == null) { // this is now allowed if (LogFilter.logDebug) { Debug.LogWarning("Ready with no player object"); } @@ -932,21 +893,19 @@ static void OnRemovePlayerMessage(NetworkMessage netMsg) RemovePlayerMessage msg = new RemovePlayerMessage(); netMsg.ReadMessage(msg); - PlayerController player = null; - netMsg.conn.GetPlayerController(msg.playerControllerId, out player); - if (player != null) + if (netMsg.conn.playerController != null) { - netMsg.conn.RemovePlayerController(msg.playerControllerId); - Destroy(player.gameObject); + netMsg.conn.RemovePlayerController(); + Destroy(netMsg.conn.playerController.gameObject); } else { - if (LogFilter.logError) { Debug.LogError("Received remove player message but could not find the player ID: " + msg.playerControllerId); } + if (LogFilter.logError) { Debug.LogError("Received remove player message but connection has no player"); } } } // Handle command from specific player, this could be one of multiple players on a single client - static void OnCommandMessage(NetworkMessage netMsg) + static void OnCommandMessage(NetworkMessage netMsg) { CommandMessage message = netMsg.ReadMessage(); @@ -965,10 +924,9 @@ static void OnCommandMessage(NetworkMessage netMsg) } // Commands can be for player objects, OR other objects with client-authority - // => check if there is no owner - if (!netMsg.conn.playerControllers.Any( - pc => pc.gameObject != null && - pc.gameObject.GetComponent().netId == uv.netId)) + // -> so if this connection's controller has a different netId then + // only allow the command if clientAuthorityOwner + if (netMsg.conn.playerController != null && netMsg.conn.playerController.netId != uv.netId) { if (uv.clientAuthorityOwner != netMsg.conn) { @@ -1063,17 +1021,17 @@ internal static void SendSpawnMessage(NetworkIdentity uv, NetworkConnection conn } } - public static void DestroyPlayersForConnection(NetworkConnection conn) + public static void DestroyPlayerForConnection(NetworkConnection conn) { - if (conn.playerControllers.Count == 0) + if (conn.playerController == null) { - // list is empty if players are still in a lobby etc., no need to show a warning + // null if players are still in a lobby etc., no need to show a warning return; } if (conn.clientOwnedObjects != null) { - var tmp = new HashSet(conn.clientOwnedObjects); + HashSet tmp = new HashSet(conn.clientOwnedObjects); foreach (var netId in tmp) { var obj = FindLocalObject(netId); @@ -1084,24 +1042,12 @@ public static void DestroyPlayersForConnection(NetworkConnection conn) } } - for (int i = 0; i < conn.playerControllers.Count; i++) + if (conn.playerController != null) { - var player = conn.playerControllers[i]; - if (player.IsValid) - { - if (player.unetView == null) - { - // the playerController's object has been destroyed, but RemovePlayerForConnection was never called. - // this is ok, just dont double destroy it. - } - else - { - DestroyObject(player.unetView, true); - } - player.gameObject = null; - } + DestroyObject(conn.playerController, true); } - conn.playerControllers.Clear(); + + conn.RemovePlayerController(); } static void UnSpawnObject(GameObject obj) diff --git a/Mirror/Runtime/PlayerController.cs b/Mirror/Runtime/PlayerController.cs deleted file mode 100644 index f5aa11adf..000000000 --- a/Mirror/Runtime/PlayerController.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using UnityEngine; - -namespace Mirror -{ - // This class represents the player entity in a network game, there can be multiple players per client - // when there are multiple people playing on one machine - // The server has one connection per client, and the connection has the player instances of that client - // The client has player instances as member variables (should this be removed and just go though the connection like the server does?) - public class PlayerController - { - public short playerControllerId = -1; - public NetworkIdentity unetView; - public GameObject gameObject; - - public const int MaxPlayersPerClient = 32; - - public PlayerController() - { - } - - public bool IsValid { get { return playerControllerId != -1; } } - - internal PlayerController(GameObject go, short playerControllerId) - { - gameObject = go; - unetView = go.GetComponent(); - this.playerControllerId = playerControllerId; - } - - public override string ToString() - { - return string.Format("ID={0} NetworkIdentity NetID={1} Player={2}", new object[] { playerControllerId, (unetView != null ? unetView.netId.ToString() : "null"), (gameObject != null ? gameObject.name : "null") }); - } - } -} diff --git a/Mirror/Weaver/Weaver.cs b/Mirror/Weaver/Weaver.cs index 331b7f803..92cd224fe 100644 --- a/Mirror/Weaver/Weaver.cs +++ b/Mirror/Weaver/Weaver.cs @@ -80,7 +80,6 @@ class Weaver public static MethodReference MemoryStreamCtor; public static MethodReference getComponentReference; public static MethodReference getUNetIdReference; - public static MethodReference getPlayerIdReference; public static TypeReference NetworkIdentityType; public static TypeReference NetworkInstanceIdType; public static TypeReference NetworkSceneIdType; @@ -1446,7 +1445,6 @@ static void SetupTargetTypes() gameObjectInequality = ResolveMethod(unityObjectType, "op_Inequality"); UBehaviourIsServer = ResolveMethod(NetworkBehaviourType, "get_isServer"); - getPlayerIdReference = ResolveMethod(NetworkBehaviourType, "get_playerControllerId"); setSyncVarReference = ResolveMethod(NetworkBehaviourType, "SetSyncVar"); setSyncVarHookGuard = ResolveMethod(NetworkBehaviourType, "set_syncVarHookGuard"); getSyncVarHookGuard = ResolveMethod(NetworkBehaviourType, "get_syncVarHookGuard");