I have this in-scene object, but when when scene starts, the OnNetworkSpawn of my NetworkBehaviorGameController object does not run unless I press this button on the inspector.
Why is this not “spawned” automatically?
I can call gameObject.GetComponent<NetworkObject>().Spawn(); from the GameController and then OnNetworkSpawn will fire, but I don’t think that’s how you’re supposed to do it.
Here you can see that the NetworkManager is present and hosting.
I have a menu scene before this which contains the NetworkManager. The game scene shown in the images is loaded by NetworkManager.Singleton.SceneManager.LoadScene() from the menu scene. I start hosting before I load the scene.
The GameController exists only in the game scene.
I did a test by loading the game scene directly, adding a NetworkManager to an empty game object, then clicking Host form the inspector, and then I was able to see that the OnNetworkSpawn fired from my GameController script.
Your GameController is in DontDestroyOnLoad which is technically a different scene and not networked. So whatever causes the GameController object to be moved to DDOL needs to be removed. I believe you can’t network spawn DDOL objects.
Given the number and purpose of the scripts on the GameController you’re best adviced to split these apart. It’s often better to have multiple objects with just one or two related scripts rather than a single object that “controls” or “manages” a whole lot of things.
Here I’d say it warrants separate objects that handle RPC communication, one for Tile handling, one for scene handling, one for voice chat, one for gui and one for the game. Not all of which necessarily need to be networked objects.
And at least some of these objects should be added to the very first scene if you need them to be in DDOL - which effectively means you’ll never want them to get destroyed. This is far easier to work with and avoids common issues of cleaning up (destroying) objects at the right time. You can have the DDOL objects respond to events raised when the MP session starts and ends, so they do the right thing at that point.
When you exit the MP session and return to menu, you may end up with a duplicate NetworkManager.
To properly fix that the NetworkManager needs to be in a scene that never gets loaded again, eg a scene before the main menu which does nothing but load the main menu. Same for all other DDOL objects.
In addition to what @CodeSmile posted, you might find this example project a useful point of reference.
It has a basic “get up and running” framework with several NetworkBehaviour components that you might find useful. It includes the use of in-scene placed NetworkObjects too.