fix: NetworkIdentity.isLocalPlayer is only set, but never reset. fixes a bug where isLocalPlayer would be false in OnDestroy, so some components couldn't rely on it in OnDestroy. fixes #2615 (this is also faster than comparing ClientScene.localPlayer each time) (#2616)

* fix: NetworkIdentity.isLocalPlayer is only set, but never reset. fixes a bug where isLocalPlayer would be false in OnDestroy, so some components couldn't rely on it in OnDestroy. fixes #2615 (this is also faster than comparing ClientScene.localPlayer each time)

* fix: NetworkIdentity.OnStartClient now sets isLocalPlayer early so isLocalPlayer is true in OnStartClient callbacks already
This commit is contained in:
vis2k 2021-03-06 19:30:16 +08:00 committed by GitHub
parent 1fb8990f39
commit a6f6f80f65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -144,7 +144,18 @@ public sealed class NetworkIdentity : MonoBehaviour
public bool isServer { get; internal set; } public bool isServer { get; internal set; }
/// <summary>Return true if this object represents the player on the local machine.</summary> /// <summary>Return true if this object represents the player on the local machine.</summary>
public bool isLocalPlayer => ClientScene.localPlayer == this; //
// IMPORTANT:
// OnStartLocalPlayer sets it to true. we NEVER set it to false after.
// otherwise components like Skillbars couldn't use OnDestroy()
// for saving, etc. since isLocalPlayer may have been reset before
// OnDestroy was called.
//
// we also DO NOT make it dependent on ClientScene.localPlayer or similar.
// we set it, then never change it. that's the user's expectation too.
//
// => fixes https://github.com/vis2k/Mirror/issues/2615
public bool isLocalPlayer { get; internal set; }
/// <summary>True if this object only exists on the server</summary> /// <summary>True if this object only exists on the server</summary>
public bool isServerOnly => isServer && !isClient; public bool isServerOnly => isServer && !isClient;
@ -690,6 +701,15 @@ internal void OnStartServer()
// set isServer flag // set isServer flag
isServer = true; isServer = true;
// set isLocalPlayer earlier, in case OnStartLocalplayer is called
// AFTER OnStartClient, in which case it would still be falsse here.
// many projects will check isLocalPlayer in OnStartClient though.
// TODO ideally set isLocalPlayer when ClientScene.localPlayer is set?
if (ClientScene.localPlayer == this)
{
isLocalPlayer = true;
}
// If the instance/net ID is invalid here then this is an object instantiated from a prefab and the server should assign a valid ID // If the instance/net ID is invalid here then this is an object instantiated from a prefab and the server should assign a valid ID
// NOTE: this might not be necessary because the above m_IsServer // NOTE: this might not be necessary because the above m_IsServer
// check already checks netId. BUT this case here checks only // check already checks netId. BUT this case here checks only
@ -766,6 +786,15 @@ internal void OnStartClient()
isClient = true; isClient = true;
// set isLocalPlayer earlier, in case OnStartLocalplayer is called
// AFTER OnStartClient, in which case it would still be falsse here.
// many projects will check isLocalPlayer in OnStartClient though.
// TODO ideally set isLocalPlayer when ClientScene.localPlayer is set?
if (ClientScene.localPlayer == this)
{
isLocalPlayer = true;
}
// Debug.Log("OnStartClient " + gameObject + " netId:" + netId); // Debug.Log("OnStartClient " + gameObject + " netId:" + netId);
foreach (NetworkBehaviour comp in NetworkBehaviours) foreach (NetworkBehaviour comp in NetworkBehaviours)
{ {
@ -793,6 +822,8 @@ internal void OnStartLocalPlayer()
return; return;
previousLocalPlayer = this; previousLocalPlayer = this;
isLocalPlayer = true;
foreach (NetworkBehaviour comp in NetworkBehaviours) foreach (NetworkBehaviour comp in NetworkBehaviours)
{ {
// an exception in OnStartLocalPlayer should be caught, so that // an exception in OnStartLocalPlayer should be caught, so that
@ -1243,6 +1274,7 @@ internal void Reset()
clientStarted = false; clientStarted = false;
isClient = false; isClient = false;
isServer = false; isServer = false;
isLocalPlayer = false;
netId = 0; netId = 0;
connectionToServer = null; connectionToServer = null;