Non Automatic Character Spawning
In many situations you don't want to automatically spawn your character with the Auto Spawn Character option in the EMI_NetworkManager. So for example you can have a UI button that will spawn in your character. First make sure Auto Create Player is true and Auto Spawn Character is false in the EMI_NetworkManager.
There are two ways to spawn a character.
Client Based Spawning
The following shows a method you can use by having the Client request the server to spawn the desired character for you:
public virtual void MyRequestSpawnCharacterOption()
{
EMI_NetworkManager.instance.RequestSpawnCharacter(
"MyCharacterPrefab",
PointsUtil.PointType.NetworkSpawnPoint,
SceneManager.GetActiveScene().name,
"MyNetworkSpawnPointName",
"",
""
);
}
As simple as that, now the server will receive that requested information and take care of spawning your character, moving them to the proper scene, and snapping them to a point type of PointsUtil.PointType.NetworkSpawnPoint with the name MyNetworkSpawnPointName.
Look at the RequestSpawnCharacter function in the EMI_NetworkManager for more options on what this is capable of doing.
Server Based Spawning
The following shows a way to have the server spawn the character on behalf of a target client. As always before attempting this make sure that client has a PlayerPrefab (aka ClientConnection) spawned. You can guarantee this by selecting the Auto Create Player tickbox on the EMI_NetworkManager.
Now since the SpawnCharacter function isn't public you will need to modify the EMI_NetworkManager to your needs by overridding it. Here is an example of an overridden version of the EMI_NetworkManager
namespace EMI.Managers
{
public class MyCustomNetworkManager : EMI_NetworkManager
{
...
...
}
}
Then use the copy and paste emi context menus to copy over all your settings to the new component and remove EMI_NetworkManager.
Then in your overridden component you can expose the SpawnPlayer function like the following:
namespace EMI.Managers
{
public class MyCustomNetworkManager : EMI_NetworkManager
{
public virtual void SpawnCharacterForClientConnection(NetworkConnection conn)
{
SpawnPlayer(conn, new SpawnPlayer {
prefabName = "CharacterPrefabName",
pointType = PointsUtil.PointType.NetworkSpawnPoint,
sceneName = "MyDesiredSceneName",
pointName = "MyPointName",
teamName = "",
unloadScene = ""
});
}
}
}
Then you could call it like the following:
NetworkConnection targetConnection = ClientUtil.GetClientConnection(12345).GetComponent<NetworkIdentity>().connectionToClient;
((MyCustomNetworkManager)EMI_NetworkManager.instance).SpawnCharacterForClientConnection(targetConnection);
or, the following which is faster:
NetworkConnection targetConnection = EMI_NetworkManager.instance.playerList[12345].GetComponent<NetworkIdentity>().connectionToClient;
((MyCustomNetworkManager)EMI_NetworkManager.instance).SpawnCharacterForClientConnection(targetConnection);
Where 12345 is the connection id you want to target. You will have to come up with a desired way to obtain that connection id.
You can find a list of all ClientConnection clients using the playerList list available in EMI_NetworkManager.