@@ -12,18 +12,17 @@ namespace Unity.Multiplayer.Samples.BossRoom.Server
12
12
[ RequireComponent ( typeof ( CharSelectData ) ) ]
13
13
public class ServerCharSelectState : GameStateBehaviour
14
14
{
15
- public override GameState ActiveState { get { return GameState . CharSelect ; } }
15
+ public override GameState ActiveState => GameState . CharSelect ;
16
16
public CharSelectData CharSelectData { get ; private set ; }
17
17
18
- private ServerGameNetPortal m_ServerNetPortal ;
18
+ Coroutine m_WaitToEndLobbyCoroutine ;
19
19
20
- private void Awake ( )
20
+ void Awake ( )
21
21
{
22
22
CharSelectData = GetComponent < CharSelectData > ( ) ;
23
- m_ServerNetPortal = GameObject . FindGameObjectWithTag ( "GameNetPortal" ) . GetComponent < ServerGameNetPortal > ( ) ;
24
23
}
25
24
26
- private void OnClientChangedSeat ( ulong clientId , int newSeatIdx , bool lockedIn )
25
+ void OnClientChangedSeat ( ulong clientId , int newSeatIdx , bool lockedIn )
27
26
{
28
27
int idx = FindLobbyPlayerIdx ( clientId ) ;
29
28
if ( idx == - 1 )
@@ -93,7 +92,7 @@ private void OnClientChangedSeat(ulong clientId, int newSeatIdx, bool lockedIn)
93
92
/// <summary>
94
93
/// Returns the index of a client in the master LobbyPlayer list, or -1 if not found
95
94
/// </summary>
96
- private int FindLobbyPlayerIdx ( ulong clientId )
95
+ int FindLobbyPlayerIdx ( ulong clientId )
97
96
{
98
97
for ( int i = 0 ; i < CharSelectData . LobbyPlayers . Count ; ++ i )
99
98
{
@@ -107,7 +106,7 @@ private int FindLobbyPlayerIdx(ulong clientId)
107
106
/// Looks through all our connections and sees if everyone has locked in their choice;
108
107
/// if so, we lock in the whole lobby, save state, and begin the transition to gameplay
109
108
/// </summary>
110
- private void CloseLobbyIfReady ( )
109
+ void CloseLobbyIfReady ( )
111
110
{
112
111
foreach ( CharSelectData . LobbyPlayerState playerInfo in CharSelectData . LobbyPlayers )
113
112
{
@@ -122,10 +121,42 @@ private void CloseLobbyIfReady()
122
121
SaveLobbyResults ( ) ;
123
122
124
123
// Delay a few seconds to give the UI time to react, then switch scenes
125
- StartCoroutine ( WaitToEndLobby ( ) ) ;
124
+ m_WaitToEndLobbyCoroutine = StartCoroutine ( WaitToEndLobby ( ) ) ;
126
125
}
127
126
128
- private void SaveLobbyResults ( )
127
+ /// <summary>
128
+ /// Cancels the process of closing the lobby, so that if a new player joins, they are able to chose a character.
129
+ /// </summary>
130
+ void CancelCloseLobby ( )
131
+ {
132
+ if ( m_WaitToEndLobbyCoroutine != null )
133
+ {
134
+ StopCoroutine ( m_WaitToEndLobbyCoroutine ) ;
135
+ }
136
+ CharSelectData . IsLobbyClosed . Value = false ;
137
+ // Set all players unready so they can react to this cancellation
138
+ SetAllUnready ( ) ;
139
+ }
140
+
141
+ void SetAllUnready ( )
142
+ {
143
+ for ( int i = 0 ; i < CharSelectData . LobbyPlayers . Count ; ++ i )
144
+ {
145
+ // Set all locked players to active so that they have to confirm their choice again
146
+ if ( CharSelectData . LobbyPlayers [ i ] . SeatState == CharSelectData . SeatState . LockedIn )
147
+ {
148
+ CharSelectData . LobbyPlayers [ i ] = new CharSelectData . LobbyPlayerState (
149
+ CharSelectData . LobbyPlayers [ i ] . ClientId ,
150
+ CharSelectData . LobbyPlayers [ i ] . PlayerName ,
151
+ CharSelectData . LobbyPlayers [ i ] . PlayerNum ,
152
+ CharSelectData . SeatState . Active ,
153
+ CharSelectData . LobbyPlayers [ i ] . SeatIdx ,
154
+ CharSelectData . LobbyPlayers [ i ] . LastChangeTime ) ;
155
+ }
156
+ }
157
+ }
158
+
159
+ void SaveLobbyResults ( )
129
160
{
130
161
foreach ( CharSelectData . LobbyPlayerState playerInfo in CharSelectData . LobbyPlayers )
131
162
{
@@ -141,7 +172,7 @@ private void SaveLobbyResults()
141
172
}
142
173
}
143
174
144
- private IEnumerator WaitToEndLobby ( )
175
+ IEnumerator WaitToEndLobby ( )
145
176
{
146
177
yield return new WaitForSeconds ( 3 ) ;
147
178
NetworkManager . SceneManager . LoadScene ( "BossRoom" , LoadSceneMode . Single ) ;
@@ -177,15 +208,15 @@ public override void OnNetworkSpawn()
177
208
}
178
209
}
179
210
180
- private void OnSceneEvent ( SceneEvent sceneEvent )
211
+ void OnSceneEvent ( SceneEvent sceneEvent )
181
212
{
182
213
// We need to filter out the event that are not a client has finished loading the scene
183
214
if ( sceneEvent . SceneEventType != SceneEventType . LoadComplete ) return ;
184
215
// When the client finishes loading the Lobby Map, we will need to Seat it
185
216
SeatNewPlayer ( sceneEvent . ClientId ) ;
186
217
}
187
218
188
- private int GetAvailablePlayerNumber ( )
219
+ int GetAvailablePlayerNumber ( )
189
220
{
190
221
for ( int possiblePlayerNumber = 0 ; possiblePlayerNumber < CharSelectData . k_MaxLobbyPlayers ; ++ possiblePlayerNumber )
191
222
{
@@ -213,8 +244,14 @@ bool IsPlayerNumberAvailable(int playerNumber)
213
244
return ! found ;
214
245
}
215
246
216
- private void SeatNewPlayer ( ulong clientId )
247
+ void SeatNewPlayer ( ulong clientId )
217
248
{
249
+ // If lobby is closing and waiting to start the game, cancel to allow that new player to select a character
250
+ if ( CharSelectData . IsLobbyClosed . Value )
251
+ {
252
+ CancelCloseLobby ( ) ;
253
+ }
254
+
218
255
SessionPlayerData ? sessionPlayerData = SessionManager < SessionPlayerData > . Instance . GetPlayerData ( clientId ) ;
219
256
if ( sessionPlayerData . HasValue )
220
257
{
@@ -235,7 +272,7 @@ private void SeatNewPlayer(ulong clientId)
235
272
}
236
273
}
237
274
238
- private void OnClientDisconnectCallback ( ulong clientId )
275
+ void OnClientDisconnectCallback ( ulong clientId )
239
276
{
240
277
// clear this client's PlayerNumber and any associated visuals (so other players know they're gone).
241
278
for ( int i = 0 ; i < CharSelectData . LobbyPlayers . Count ; ++ i )
@@ -246,6 +283,19 @@ private void OnClientDisconnectCallback(ulong clientId)
246
283
break ;
247
284
}
248
285
}
286
+
287
+
288
+ if ( CharSelectData . IsLobbyClosed . Value )
289
+ {
290
+ // If lobby is closing and waiting to start the game, cancel so that other players can react to it, and
291
+ // wait for the player coming back if they want to.
292
+ CancelCloseLobby ( ) ;
293
+ }
294
+ else
295
+ {
296
+ // If it is not closing, set everyone as unready for the same reason
297
+ SetAllUnready ( ) ;
298
+ }
249
299
}
250
300
}
251
301
}
0 commit comments