NetworkManagerCharacterSelection.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. using UnityEngine;
  2. namespace Mirror.Examples.CharacterSelection
  3. {
  4. public class NetworkManagerCharacterSelection : NetworkManager
  5. {
  6. // See the scene 'SceneMapSpawnWithNoCharacter', to spawn as empty player.
  7. // 'SceneMap' will auto spawn as random player character.
  8. // Compare Network Manager inspector setups to see the difference between the two.
  9. // Either of these allow selecting character after spawning in too.
  10. public bool SpawnAsCharacter = true;
  11. public static new NetworkManagerCharacterSelection singleton { get; private set; }
  12. private CharacterData characterData;
  13. public override void Awake()
  14. {
  15. characterData = CharacterData.characterDataSingleton;
  16. if (characterData == null)
  17. {
  18. Debug.Log("Add CharacterData prefab singleton into the scene.");
  19. return;
  20. }
  21. base.Awake();
  22. singleton = this;
  23. }
  24. public struct CreateCharacterMessage : NetworkMessage
  25. {
  26. public string playerName;
  27. public int characterNumber;
  28. public Color characterColour;
  29. }
  30. public struct ReplaceCharacterMessage : NetworkMessage
  31. {
  32. public CreateCharacterMessage createCharacterMessage;
  33. }
  34. public override void OnStartServer()
  35. {
  36. base.OnStartServer();
  37. NetworkServer.RegisterHandler<CreateCharacterMessage>(OnCreateCharacter);
  38. NetworkServer.RegisterHandler<ReplaceCharacterMessage>(OnReplaceCharacterMessage);
  39. }
  40. public override void OnClientConnect()
  41. {
  42. base.OnClientConnect();
  43. if (SpawnAsCharacter)
  44. {
  45. // you can send the message here, or wherever else you want
  46. CreateCharacterMessage characterMessage = new CreateCharacterMessage
  47. {
  48. playerName = StaticVariables.playerName,
  49. characterNumber = StaticVariables.characterNumber,
  50. characterColour = StaticVariables.characterColour
  51. };
  52. NetworkClient.Send(characterMessage);
  53. }
  54. }
  55. void OnCreateCharacter(NetworkConnectionToClient conn, CreateCharacterMessage message)
  56. {
  57. Transform startPos = GetStartPosition();
  58. // check if the save data has been pre-set
  59. if (message.playerName == "")
  60. {
  61. Debug.Log("OnCreateCharacter name invalid or not set, use random.");
  62. message.playerName = "Player: " + UnityEngine.Random.Range(100, 1000);
  63. }
  64. // check that prefab is set, or exists for saved character number data
  65. // could be a cheater, or coding error, or different version conflict
  66. if (message.characterNumber <= 0 || message.characterNumber >= characterData.characterPrefabs.Length)
  67. {
  68. Debug.Log("OnCreateCharacter prefab Invalid or not set, use random.");
  69. message.characterNumber = UnityEngine.Random.Range(1, characterData.characterPrefabs.Length);
  70. }
  71. // check if the save data has been pre-set
  72. if (message.characterColour == new Color(0, 0, 0, 0))
  73. {
  74. Debug.Log("OnCreateCharacter colour invalid or not set, use random.");
  75. message.characterColour = Random.ColorHSV(0f, 1f, 1f, 1f, 0f, 1f);
  76. }
  77. GameObject playerObject = startPos != null
  78. ? Instantiate(characterData.characterPrefabs[message.characterNumber], startPos.position, startPos.rotation)
  79. : Instantiate(characterData.characterPrefabs[message.characterNumber]);
  80. // Apply data from the message however appropriate for your game
  81. // Typically Player would be a component you write with syncvars or properties
  82. CharacterSelection characterSelection = playerObject.GetComponent<CharacterSelection>();
  83. characterSelection.playerName = message.playerName;
  84. characterSelection.characterNumber = message.characterNumber;
  85. characterSelection.characterColour = message.characterColour;
  86. // call this to use this gameobject as the primary controller
  87. NetworkServer.AddPlayerForConnection(conn, playerObject);
  88. }
  89. void OnReplaceCharacterMessage(NetworkConnectionToClient conn, ReplaceCharacterMessage message)
  90. {
  91. // Cache a reference to the current player object
  92. GameObject oldPlayer = conn.identity.gameObject;
  93. GameObject playerObject = Instantiate(characterData.characterPrefabs[message.createCharacterMessage.characterNumber], oldPlayer.transform.position, oldPlayer.transform.rotation);
  94. // Instantiate the new player object and broadcast to clients
  95. // Include true for keepAuthority paramater to prevent ownership change
  96. NetworkServer.ReplacePlayerForConnection(conn, playerObject, true);
  97. // Apply data from the message however appropriate for your game
  98. // Typically Player would be a component you write with syncvars or properties
  99. CharacterSelection characterSelection = playerObject.GetComponent<CharacterSelection>();
  100. characterSelection.playerName = message.createCharacterMessage.playerName;
  101. characterSelection.characterNumber = message.createCharacterMessage.characterNumber;
  102. characterSelection.characterColour = message.createCharacterMessage.characterColour;
  103. // Remove the previous player object that's now been replaced
  104. // Delay is required to allow replacement to complete.
  105. Destroy(oldPlayer, 0.1f);
  106. }
  107. public void ReplaceCharacter(ReplaceCharacterMessage message)
  108. {
  109. NetworkClient.Send(message);
  110. }
  111. }
  112. }