파트 4 - 게임 매니저와 레벨
이 섹션에서는 룸 안에서 현재 플레이하고 있는 플레이어 수에 기반한 다양한 레벨 로딩 처리에 대한 추가적인 기능을 다룰 것 입니다.
경기장 로딩 루틴
4개의 다른 룸을 생성하였으며 플레이어 수의 마지막 문자로 룸의 이름을 지었기 때문에 룸안의 현재 플레이어 수와 관련된 신을 bind 하는 것은 매우 쉽습니다.
"convention over configuration" 로 알려져 있는 매우 효율적인 테크닉이며 "환경설정"기반 접근법으로 예를 들어 주어진 룸 안의 플레이어 수로 신 이름의 테이블 목록을 찾아 유지관리하는 것이 쉽습니다.
GameManager
스크립트를 오픈 합니다.- region Private Methods 영역에 새로운 메소드를 추가할 것 입니다.
GameManager
스크립트를 저장하는 것을 잊지 마세요.
C#
#region Private Methods
void LoadArena()
{
if ( ! PhotonNetwork.isMasterClient )
{
Debug.LogError( "PhotonNetwork : Trying to Load a level but we are not the master Client" );
}
Debug.Log( "PhotonNetwork : Loading Level : " + PhotonNetwork.room.playerCount );
PhotonNetwork.LoadLevel("Room for "+PhotonNetwork.room.playerCount);
}
#endregion
이 메소드를 호출 할 때에 현재 있는 룸의 playerCound 프로퍼티에 기반한 룸을 로드 할 것 입니다.
여기에서 두가지의 주의 할 점들이 있으며 매우 중요 합니다.
- PhotonNetwork.LoadLevel() 는 마스터인 경우에만 호출 되어야 합니다. 따라서 PhotonNetwork.isMasterClient 를 이용하여 마스터인지를 체크 합니다.
이 것을 체크하는 것은 호출자의 책임이 될 것 이며 이 섹션의 다음 파트에서 다룰 것 입니다. - PhotonNetwork.LoadLevel()을 이용하여 원하는 레벨을 로드 합니다. 이 게임에서는 PhotonNetwork.automaticallySyncScene 을 사용하도록 해놓았기 때문에 룸 안의 모든 접속한 클라이언트에 대해 이 레벨 로드를 유니티가 직접 하는 것이 아닌 Photon 이 하도록 하였습니다.
이제 원하는 레벨을 로드하는 기능이 있으므로 플레이여 접속과 접속해제에 대하여 바인드 해 보겠습니다.
플레이어들의 연결 관찰
현재 GameManager
는 일반적인 MonoBehaviour 스크립트입니다. 이 튜토리얼 이전 파트에서 Photon 콜백을 얻는 다양 한 방식을 학습했기 때문에 GameManager
에서 플레이어 접속과 접속해제를 Listen 할 필요가 있습니다.
다음을 구현해 봅시다.
GameManager
스크립트를 오픈합니다.기본 클래스를 MonoBehaviour 에서 Photon.PunBehaviour 로 변경합니다.
C#
public class GameManager : Photon.PunBehaviour {
다음의 Photon 콜백 메시지를 추가하고
GameManager
스크립트를 저장 합니다.
C#
#region Photon Messages
public override void OnPhotonPlayerConnected( PhotonPlayer other )
{
Debug.Log( "OnPhotonPlayerConnected() " + other.name ); // not seen if you're the player connecting
if ( PhotonNetwork.isMasterClient )
{
Debug.Log( "OnPhotonPlayerConnected isMasterClient " + PhotonNetwork.isMasterClient ); // called before OnPhotonPlayerDisconnected
LoadArena();
}
}
public override void OnPhotonPlayerDisconnected( PhotonPlayer other )
{
Debug.Log( "OnPhotonPlayerDisconnected() " + other.name ); // seen when other disconnects
if ( PhotonNetwork.isMasterClient )
{
Debug.Log( "OnPhotonPlayerConnected isMasterClient " + PhotonNetwork.isMasterClient ); // called before OnPhotonPlayerDisconnected
LoadArena();
}
}
#endregion
이제 설정이 완료 되었습니다. 플레이어들이 참여 또는 룸을 떠날 때 마다 통지를 받게 되고 위에서 구축 해 놓은 LoadArena()
메소드를 호출 할 것 입니다.
하지만 PhotonNetwork.isMasterClient를 이용하여 마스터인 경우에만 LoadArena()
를 호출 할 것 입니다.
이제 로비로 되돌아와서 룸에 참여할 때 맞는 신을 로드 할 수 있습니다.
로비에서 경기장 로딩
Launcher
스크립트를 편집 합니다.OnJoinedroom()
메소드에 다음을 추가하고Launcher
스크립트를 저장 합니다.
C#
// #Critical: We only load if we are the first player, else we rely on PhotonNetwork.automaticallySyncScene to sync our instance scene.
if (PhotonNetwork.room.playerCount == 1)
{
Debug.Log("We load the 'Room for 1' ");
// #Critical
// Load the Room Level.
PhotonNetwork.LoadLevel("Room for 1");
}
Launcher
신을 오픈 후 실행하여 테스트 해 봅시다. "Play" 를 클릭하여 시스템이 연결하고 룸에 참여하도록 합니다.
다 되었습니다. 이제 로비가 있거나 또는 작업 중 입니다. 하지만 룸을 나간 경우 다시 로비로 돌아왔을 때 자동으로 재 참여 하게 됩니다.
아직 이렇게 되지 않는 다면 "간단하게" 로그를 분석 해 봅니다.
직접 해 보세요. 아직 소스에서 문제를 발견 하지 못했다면 같이 해 보겠습니다.
Launcher
신을 실행 합니다.- "Play" 버튼을 누르고 "Room for 1" 에 참여하여 로드될 때 까지 기다립니다.
- Unity Console 창을 clear 합니다.
- "Leave Room" 을 누릅니다.
- Unity Console 관찰하여 "DemoAnimator/Launcher: OnConnectedToMaster() was called by PUN" 이 기록되어 있는지 확인 합니다.
Launcher
신을 중지 합니다.- 로그 항목 "DemoAnimator/Launcher: OnConnectedToMaster() was called by PUN" 를 더블 클릭하면 해당 호출이 발생하 지점으로 스크립트가 로드 됩니다.
- 음.... 연결 되면 매번 알림을 받게 되고 자동적으로 JoinRandomRoom 으로 참여 하지만 우리가 원하는 것이 아닙니다.
이것을 고치기 위해서 우리는 컨텍스트에 대해서 알 필요가 있습니다. 사용자가 "Play" 버튼을 누를 때 , 사용자에 의해서 접속이 진행 중이라는 플래그를 얻어야 합니다.
그리고 나서 이 플래그를 체크하여 다양한 Photon 콜백내에서 적절하게 처리 해 주어야 합니다.
Launcher
스크립트를 편집 합니다.Private Variables regions 에서 새로운 프로퍼티를 생성 합니다.
C#
/// <summary> /// Keep track of the current process. Since connection is asynchronous and is based on several callbacks from Photon, /// we need to keep track of this to properly adjust the behavior when we receive call back by Photon. /// Typically this is used for the OnConnectedToMaster() callback. /// </summary> bool isConnecting;
connect()
메소드의 첫 부분에 다음을 추가 합니다.C#
// keep track of the will to join a room, because when we come back from the game we will get a callback that we are connected, so we need to know what to do then isConnecting = true;
OnConnectedMaster()
메소드에서 다음의if
문장안에PhotonNetwork.JoinRandomRoom()
를 놓습니다.C#
// we don't want to do anything if we are not attempting to join a room. // this case where isConnecting is false is typically when you lost or quit the game, when this level is loaded, OnConnectedToMaster will be called, in that case // we don't want to do anything. if (isConnecting) { // #Critical: The first we try to do is to join a potential existing room. If there is, good, else, we'll be called back with OnPhotonRandomJoinFailed() PhotonNetwork.JoinRandomRoom(); }
다시 Launcher 신을 실행하여 테스트 하여 로비와 게임 사이를 왔다 갔다 해보면 모든 것이 잘 됩니다 :)
신의 자동 동기화 테스트를 하기 위해서는 어플리케이션을 게시(테스트시 가장 빠른 데스크탑용으로) 해야할 필요가 있으며 유니티와 동시에 실행시켜 두 명의 플레이어들이 연결되고 룸에 참여 할 수 있도록 합니다.
만약 유니티 에디터가 먼저 룸을 생성하게 되면 MasterClient 가 되기 때문에 유니티 콘솔에서 "PhotonNetwork : Loading Level : 1" 로그를 확인 할 수 있고 게시된 인스턴스로 접속 할 때 "PhotonNetwork : Loading Level : 2" 로그를 체크할 수 있습니다.
좋습니다! 많이 진행하였으나 전체 작업의 반일 뿐 입니다... :) 플레이어 자체와 씨름할 필요가 있고 다음 섹션에서 다루게 될 것 입니다.
가끔 컴퓨터와 멀리 떨어져 휴식을 취해 보세요. 다양한 개념이 설명되므로 휴식을 한 후 집중하면 더 효과가 있을 것 입니다.
특정 기능에 의문이 있거나 튜토리얼을 따라하는데 어려움이 있고 여기에서 다루지 않은 오류들이 발생 했을 때 포럼으로 질문 하는 것을 주저하지 마세요. 기꺼이 도와 드리도록 하겠습니다. :)
Back to top