Inconsistencies for `IsHost`, `IsClient`, `IsServer` between `NetworkBehavior` and `NetworkManager`
See original GitHub issueDescription
The properties IsHost
, IsClient
, and IsServer
of NetworkBehavior
do not return the same value as the matching properties in NetworkManager
if the associated NetworkObject
has not yet been spawned.
Reproduce Steps
In a NetworkBehavior
define the method:
// MyNetworkBehvaior.cs
public void AssertIsClient() {
Debug.Assert(IsClient == NetworkManager.IsClient, "IsClient != NetworkManager.IsClient");
}
In the Start
method of another component call
var instance = Instantiate(myNetworkBehaviorPrefab);
instance.GetComponent<MyNetworkBehavior>().AssertIsClient();
Actual Outcome
The assertion fails since the properties do not match.
Expected Outcome
The assertion passes because the properties are consistent between NetworkBehavior
and NetworkManager
.
Environment
- OS: Windows 10
- Unity Version: 2020.3
- Netcode Version: 1.2.0
Additional Context
It looks like the properties are assigned manually in UpdateNetworkProperties()
during initialization. Is there are reason why the properties don’t just directly return the corresponding value from NetworkManager
?
Issue Analytics
- State:
- Created 7 months ago
- Comments:5 (2 by maintainers)
Top Results From Across the Web
"isServer" is false when called from NetworkManager!
Hi, In my NetworkManager derived class, I instantiate my player (which is a NetworkBehaviour) and thus calls it's Awake() and in that ...
Read more >NetworkBehaviour
You can synchronize member variables of NetworkBehaviour scripts from the server to clients. The server is authoritative in this system, so synchronization only ......
Read more >COMPLETE Unity Multiplayer Tutorial (Netcode for ... - YouTube
If you're having trouble with the new setup of NetworkManager's Network Prefabs Lists like I did, you need to add a NetworkPrefabsList to ......
Read more >Problem with Spawning at runtime and ...
When I interact with the Jenga blocks in one of the Clients, the blocks seem to not be synchronized between the Client and...
Read more >How do you stop a client/host in Unity Netcode for ...
1 Answer 1 ... Disconnects clients if connected and stops server if running. To answer your full question, you also need a Cleanup()...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@NoelStephensUnity Very helpful thank you very much
@RoxDevvv I totally understand that it can be confusing initially, but maybe I can further explain to help better clarify why it is this way: When checking any netcode property within a NetworkBehaviour, you just need to think about the context of the check. Originally, those properties would default to using NetworkManager.Singleton which led to a different set of confusion if someone was checking just “IsHost” and making the assumption that you can then proceed to invoke RPCs or change NetworkVariables since the NetworkManager “is started”…but the context is within a NetworkBehaviour component that is tied/associated with a NetworkObject and the NetworkManager could be still connecting, still synchronizing with NetworkObjects, and various other states that IsServer, IsHost, or IsClient will not be enough information to assure your netcode script will be ok to execute. You can think of a NetworkObject, when it is not spawned but its associated GameObject is instantiated, as a not fully defined (“blank/generic”) object since it has no real network session state…which means it doesn’t know about the NetworkManager, who owns it, whether it is parented or not, and such. When a NetworkObject is spawned, it has been fully initialized and knows about such things.
Going back to just using something like an “!IsServer” (i.e. client only) check within a NetworkBehaviour could lead to other issues if the NetworkObject was not spawned and that value actually was set to a value…so in reality if IsClient, IsHost, and IsServer are all false then that translates to !IsSpawned (i.e. the NetworkManager has no defined role)… of course just those values by themselves could be a lot more confusing to use than just checking IsSpawned.
In the end, we were faced with either using a singleton reference within a “getter” accessor method for NetworkBehaviour properties (i.e. IsServer, IsHost, IsClient, and even NetworkManager itself) which could be expensive (processing wise) since those properties could potentially be used in many places within a NetworkBehavior component and there could be many instances of the same NetworkBehaviour component (assigned to unique NetworkObject instances)…we made the call to just not have NetworkBehaviour netcode related properties, especially those that were pulled from the NetworkManager, assigned until the NetworkObject itself was considered spawned and the NetworkBehaviour had its OnNetworkSpawn method invoked.
The best way to handle netcode specific script within a common update method (FixedUpdate, Update, and LateUpdate) is to just exit early if IsSpawned is false. This way, any checks for things like IsServer, IsHost, or IsClient that proceed the IsSpawned check (i.e. it is true/spawned) will be guaranteed to be set to the local NetworkManager’s current setting.