티스토리 뷰

NetworkRoomManager에서 Start Host나 Start Client를 실행하면

Offline Scene에서 Online Scene으로 이동합니다.

이후에 벌어지는 일을 정리해봅니다.

 

Online Scene으로 이동하면 NetworkRoomPlayer 객체가 생성됩니다.

객체의 Start 구문에서 DontDestroyOnLoad(gameObject)가 실행됩니다.

 

그리고 싱글톤이 된 NetworkRoomManager의 RoomSlots에 자신을 추가합니다.

 

RoomSlotsNetworkRoomPlayer형 HashSet입니다.

( HashSet  : 중복 값을 허용하지 않는 고유한 값의 컬렉션)

NetworkRoomManager의 RoomSlots을 조회하면 원하는 플레이어를 호출할 수 있겠습니다.

 

이후엔 Client를 수행 중인 RoomManager에서 콜백 함수가 실행됩니다.

OnRoomClientEnter는 RoomManager의 콜백 함수로써 화면에 클라이언트 객체가 생성될 때 호출 되는 것입니다.

그와 함께 모든 플레이어 객체의 OnClientEnterRoom 콜백 함수를 실행시킵니다.

새로운 플레이어 객체가 추가될 때마다 모든 플레이어 객체에서 최신화, 초기화 해야할 일을 실행하면 좋을 것 같습니다.  

일단 두 콜백 함수는 기본적으로 비어 있습니다. base 없이 override해서 사용하 됩니다.

 

그리고 서버에서 만큼은 한가지 작업이 더 있는데,

바로 플레이어 객체들에게 번호를 부여하는 것입니다.

후위 연산자를 쓰고 있습니다.

foreach문을 사용하여 모든 플레이어 객체에 번호를 부여하는 것을 보아

번호를 부여할 때마다 모든 플레이어 객체의 번호를 갱신 하는 것으로 보이는데,

 

참조를 더 찾아보니 서버에서 클라이언트의 연결이 끊길 때마다도 호출됩니다.

1, 3, 4 ... 라던가

2, 3, 4 ... 같이 중간에 번호가 빠지는 일 없이

매번 새 번호를 부여하는 것 같습니다.

 

그럼 여기 플레이어 리스트에도 추가됩니다.

 

새로운 플레이어가 연결되면 역시나 추가됩니다.

 

이 UI는 어떤 객체 하나가 혼자서 화면에 그리는 것이 아닙니다.

현재 씬에 있는 모든 RoomPlayer 객체가

각자 GUILayout을 사용하여 자신의 정보만 그리는 것입니다.

 

Remove 버튼이 그려진 걸로 보아 위 이미지는 Host 플레이어의 화면입니다.

 

플레이어 객체가 isServer인 경우 Remove 버튼을 그리게 되어있습니다.

다른 리모트 플레이어 객체는 isServer가 아니므로 버튼을 그리지 않을 것입니다.

 

이렇게 보니 Room Manage가 부여한 Player Index 값을 사용하는 것도 유용한 것 같습니다.

사용하지 않는다면 정말 사용하지 않을 값처럼 보이기도 합니다.

 


 

Room Manager의 중요한 기능으로는

Game Play Scene으로 넘어가기 위한 조건으로

모든 플레이어가 Ready 상태인지 확인하는 것이 있습니다.

일단 기본적으로는 마지막 플레이어가 Ready를 하면 그 즉시 Game Play Scene으로 이동하게 되어있습니다.

 

ReadyToBegin은 Room Player가 게임을 시작할 수 있는 상태인지를 나타내는 bool 값으로,

[SyncVar] 속성을 가지고 있습니다.

그리고 [Hook]을 사용하여 ReadyStateChanged라는 콜백 함수도 지원합니다.

 ReadyStateChanged는 기본적으로 비어있습니다. 그냥 override 해서 사용하면 됩니다.

 

만약 GUI가 아니라 별도의 UI 버튼이나 조작키를 사용하여

값을 바꾼다면 ReadyToBegin를 직접 바꾸기보단

CmdChangeReadyState를 먼저 실행해야합니다.

접두사를 보아 서버에서 실행되는 [Command] 속성의 메서드입니다.

 

매개 변수로 바꾸려는 bool 값을 요구합니다.

이 bool 값이 그대로 readyToBegin에 할당됩니다.

그러면 자동으로 [Hook]의  ReadyStateChanged 콜백 함수가 실행됩니다.

그리고 ReadyStatusChanged 메서드가 실행됩니다.

 

이 메서드는 모든 플레이어를 조회하여 현재 준비 상태인지를 확인합니다.

(현재 연결된 플레이어 수 == 준비상태의 플레이어 수) 를 비교합니다.

모든 플레이어가 준비 상태라면 CheckReadyToBegin를 실행합니다.

만약 모두 준비 상태가 아니라면 allPlayersReady'실행'합니다.

 

CheckReadyToBegin도 간단한 검사를 합니다.

현재 준비된 플레이어의 수가

Network Manager에서 설정한 최소인원을 충족하는지를 확인할 뿐입니다.

최소인원을 갖췄다면 다시 allPlayersReady '실행'합니다.

 

여기서 bool 값을 할당 받는 allPlayersReady를 실행한다고 말했는데,

맞는 표현은 아니지만 그 bool 값 프로퍼티 내부에서

중요한 메서드가 실행되어 그렇게 표현한 것입니다.

 

프로퍼티 내부에서 새로운 값 value이 true인지 false인지 판별하여

GameScene으로 이동하는 OnRoomServerPlayersReady를 실행하거나

씬에 아무 변화를 일어나지 않는 콜백 메서드 OnRoomServerPlayersNotReady를 실행합니다.  

 

중요한 코드를 다 둘러 본 것 같습니다.

 

Game Play Scene으로 이동하기 위해선

최종적으로 ServerChangeScene(GameplayScene); 가 실행되면 됩니다.

그러나 그 과정에서 로비같은 느낌을 주기 위해선

준비 상태 UI가 잘 갱신되거나 어떤 입력에 반응하는 효과를 주어야합니다.

 


정리하자면 CmdChangeReadyState를 실행하는 것으로

많은 메서드를 거쳐 ServerChangeScene이 실행되는 것입니다.

 

 

 

기본적으로 제공되는 GUI 상에서는 위의 과정을 거칩니다만,

게임에 맞게 직접 제작한 UI에도 적용할 줄 알아야겠습니다.

 

만약 Server를 겸하는 host 플레이어라면

Lobby에 입장한 순간부터 ReadyToBegin 값이 true일 것이고

Ready 버튼은 필요 없을 것입니다.

대신 모든 플레이어들이 Ready 상태가 되면

Game Start 버튼이 활성화 되게 해야할 것입니다.

Game Start 버튼에는 ServerChangeScene(GameplayScene)이 연결될 것입니다.

 

그 밖의 Guset가 되는 Client에겐

Ready 버튼을 활성화 시켜주고,

Ready 버튼에는 CmdChangeReadyState을 연결하면 되겠습니다.

 

대략 아래의 세 단계를 생각하면 어렵지 않을 듯 싶습니다.

1. 먼저 CmdChangeReadyState를 사용하여 ReadyToBegin의 값을 바꿉니다.

2. 상태가 바뀌면 주고 싶은 변화를 ReadyStateChanged에서 구현합니다.

3. 모두 준비 상태가 되었을 때 주고 싶은 변화를 OnRoomServerPlayers Ready에서 구현합니다.

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함