-
Photon - Demo 탐색 (2)Unity 2023. 10. 29. 23:14
I. 인터페이스
1. IPunObservable
OnPhotonSerializeView()를 통해서 특정한 상황에서의 동기화 로직이나 상태 업데이트 방법을 사용자 정의할 수 있음.
// 자동으로 동기화를 하지 않고, 원하는 방법으로 동기화를 원할 경우 IPunObservable 인터페이스 사용 // 자동으로 PhotonView 컴포넌트를 추가함. public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) { if (stream.IsWriting) // 호스트인 경우 정보를 줌 { stream.SendNext(rigidbody.position); // 순서를 지켜서 주고 stream.SendNext(rigidbody.velocity); } else // 호스트가 아닌 경우 정보를 받음. { rigidbody.position = (Vector2)stream.ReceiveNext(); // 순서를 지켜서 받아야함. rigidbody.velocity = (Vector2)stream.ReceiveNext(); } }
II. 클래스
1. MonoBehaviorPun
: MonoBehavior에 photonView 프로퍼티를 더함.
: PhotonView나 RPC (Remote Procedure Call) 등의 기본적인 네트워킹 기능을 포함하여, 게임 오브젝트에 네트워크 기능을 추가할 수 있음.
: MonoBehavior을 상속받고, MonoBehaviorPunCallbacks를 상속함.
: 보통 게임 오브젝트에 네트워크 기능을 추가한 후, 게임 오브젝트간의 상호작용, 동기화 관리를 하는데 사용함.
2. MonoBehaviorPunCallbacks
: .photonView와 PUN이 에서 발생하는 다양한 이벤트와 콜백을 처리하는 클래스.
: 네트워크 요청 후, 발생하는 콜백에 대해 대응하고 싶을 때 주로 사용함.
: 보통 게임 룸, 매치메이킹, 플레이어 관리, 게임 상태 관리를 하는데 쓰임.
A. 네트워크 연결 관리
OnConnectedToMaster()
: 마스터 서버로 연결시, 호출되는 콜백 메서드
: MonoBehaviorPunCallbacks 에서는 비어있는 메서드이기 때문에, 필요할 때, 구현할 내용을 오버라이드해서 사용.
public override void OnConnectedToMaster() { this.SetActivePanel(SelectionPanel.name); }
OnJoinedLobby()
: 마스터 서버의 로비로 진입시, 호출되는 콜백 메서드
: MonoBehaviorPunCallbacks 에서는 비어있는 메서드이기 때문에, 필요할 때, 구현할 내용을 오버라이드해서 사용.
public override void OnJoinedLobby() { cachedRoomList.Clear(); ClearRoomListView(); }
B. 룸 관리
OnJoinedRoom()
: 룸에 진입시, 호출되는 콜백 메서드
: MonoBehaviorPunCallbacks 에서는 비어있는 메서드이기 때문에, 필요할 때, 구현할 내용을 오버라이드해서 사용.
public override void OnJoinedRoom() { cachedRoomList.Clear(); SetActivePanel(InsideRoomPanel.name); if (playerListEntries == null) { playerListEntries = new Dictionary<int, GameObject>(); } foreach (Player p in PhotonNetwork.PlayerList) // 방에 접속했을 때 플레이어 정보 보여줌. { GameObject entry = Instantiate(PlayerListEntryPrefab); entry.transform.SetParent(InsideRoomPanel.transform); entry.transform.localScale = Vector3.one; entry.GetComponent<PlayerListEntry>().Initialize(p.ActorNumber, p.NickName); object isPlayerReady; if (p.CustomProperties.TryGetValue(AsteroidsGame.PLAYER_READY, out isPlayerReady)) { entry.GetComponent<PlayerListEntry>().SetPlayerReady((bool) isPlayerReady); } playerListEntries.Add(p.ActorNumber, entry); } StartGameButton.gameObject.SetActive(CheckPlayersReady()); Hashtable props = new Hashtable // HashTable 사용 (Photon에서 만들어 놓음/ 위에서 using 해야함) { {AsteroidsGame.PLAYER_LOADED_LEVEL, false} }; PhotonNetwork.LocalPlayer.SetCustomProperties(props); }
: 룸에 진입하고, 플레이어의 ActorNumber과 Nickname을 파라미터로 하여, PlayerListEntry 프리팹을 인스턴스화함.
OnLeftRoom()
: 룸을 떠날 시, 호출되는 콜백 메서드
: MonoBehaviorPunCallbacks 에서는 비어있는 메서드이기 때문에, 필요할 때, 구현할 내용을 오버라이드해서 사용.
public override void OnLeftRoom() { SetActivePanel(SelectionPanel.name); foreach (GameObject entry in playerListEntries.Values) { Destroy(entry.gameObject); } playerListEntries.Clear(); playerListEntries = null; }
OnPlayerEnteredRoom()
: 플레이어가 룸에 입장할 시, 호출되는 콜백 메서드
: MonoBehaviorPunCallbacks 에서는 비어있는 메서드이기 때문에, 필요할 때, 구현할 내용을 오버라이드해서 사용.
public override void OnPlayerEnteredRoom(Player newPlayer) { GameObject entry = Instantiate(PlayerListEntryPrefab); entry.transform.SetParent(InsideRoomPanel.transform); entry.transform.localScale = Vector3.one; entry.GetComponent<PlayerListEntry>().Initialize(newPlayer.ActorNumber, newPlayer.NickName); playerListEntries.Add(newPlayer.ActorNumber, entry); StartGameButton.gameObject.SetActive(CheckPlayersReady()); }
: 플레이어의 정보를 담고 있는 PlayerListEntryPrefab에 해당 플레이어의 정보를 담아 인스턴스화
: 인스턴스화한 프리팹을 playerListEntries 리스트에 추가하여 관리.
- 파라미터
Player (새로 입장한 플레이어)
OnPlayerLeftRoom
: 플레이어가 룸에서 퇴장할 시, 호출되는 콜백 메서드
: MonoBehaviorPunCallbacks 에서는 비어있는 메서드이기 때문에, 필요할 때, 구현할 내용을 오버라이드해서 사용.
public override void OnPlayerLeftRoom(Player otherPlayer) { Destroy(playerListEntries[otherPlayer.ActorNumber].gameObject); playerListEntries.Remove(otherPlayer.ActorNumber); StartGameButton.gameObject.SetActive(CheckPlayersReady()); }
: 인스턴스화한 프리팹을 playerListEntries 리스트에서 제거함.
- 파라미터
Player (퇴장한 플레이어)
C. 플레이어 관리
OnMasterClientSwitched()
: 호스트가 바뀌었을 시, 호출되는 콜백 메서드
: MonoBehaviorPunCallbacks 에서는 비어있는 메서드이기 때문에, 필요할 때, 구현할 내용을 오버라이드해서 사용.
public override void OnMasterClientSwitched(Player newMasterClient) { if (PhotonNetwork.LocalPlayer.ActorNumber == newMasterClient.ActorNumber) { StartGameButton.gameObject.SetActive(CheckPlayersReady()); } }
- 파라미터
Player (새로 호스트로 임명된 클라이언트)
OnPlayerPropertiesUpdate()
: 플레이어의 커스텀 프로퍼티가 변경되었을 때, 호출되는 콜백 메서드
: MonoBehaviorPunCallbacks 에서는 비어있는 메서드이기 때문에, 필요할 때, 구현할 내용을 오버라이드해서 사용.
public override void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps) { if (playerListEntries == null) { playerListEntries = new Dictionary<int, GameObject>(); } GameObject entry; if (playerListEntries.TryGetValue(targetPlayer.ActorNumber, out entry)) { object isPlayerReady; if (changedProps.TryGetValue(AsteroidsGame.PLAYER_READY, out isPlayerReady)) { entry.GetComponent<PlayerListEntry>().SetPlayerReady((bool) isPlayerReady); } } StartGameButton.gameObject.SetActive(CheckPlayersReady()); }
- 파라미터
Player (커스텀 프로퍼티가 변경된 플레이어)
Hashtable (플레이어의 커스텀 프로퍼티)3. PhotonView
: PUN에서 개체를 식별하고 클라이언트가 원격 인스턴스를 업데이트하는 데 사용되는 클래스
: 네트워크(viewID)를 통해 개체를 식별하고 클라이언트가 원격 인스턴스를 업데이트하는 것에 대한 메서드를 지님.
: 모든 네트워크 오브젝트에는 PhotonView 컴포넌트가 존재해야 함.
A. 객체 식별
PhotonView.IsMine
: 현재 클라이언트의 'PhotonView'로부터 인스턴스화 된 것인지, 현재 클라이언트로 컨트롤 가능한지에 대한 여부.
: 객체 단위 구분
bool IsMine
PhotonView.AmOwner
: 호스트인지 여부
bool IsOwner
B. 원격 인스턴스 업데이트
[PunRPC]
전달할 메서드 정의()PhotonView.RPC()
: 지정한 타깃의 클라이언트로 하여금, 특정한 메서드를 실행시킬 때.
: 위의 두 형식으로 쓰일 수 있다.
- 파라미터
string (메서드 이름)
Player (메서드를 실행시킬 플레이어)
bool (encrypt)
params object[] (원격 실행시킬 메서드의 파라미터들을 요소로 가진 배열)RPC 타깃의 종류
: RPC 메서드의 Player 파라미터에 RPCTarget.<EnumElement> 으로 활용.
public enum RpcTarget { All, // 모두에게 메서드를 전달하고, 사용하는 클라이언트도 즉시 실행함. // 단, 나중에 들어오는 클라이언트는 해당 메서드를 실행하지 않음. Others, // 모두에게 메서드를 전달하고, 사용하는 클라이언트는 실행하지 않음. // 단, 나중에 들어오는 클라이언트는 해당 메서드를 실행하지 않음. MasterClient, // 호스트에게만 메서드를 전달. // 실행 전에, 호스트의 연결이 끊긴다면, 재접속할 시, 해당 메서드를 실행하지 않음 AllBuffered, // 모두에게 메서드를 전달하고, 사용하는 클라이언트도 즉시 실행함. // 나중에 들어오는 클라이언트도 buffered 되었기 때문에, 해당 메서드를 실행함. OthersBuffered, // 모두에게 메서드를 전달하고, 사용하는 클라이언트는 실행하지 않음. // 나중에 들어오는 클라이언트도 buffered 되었기 때문에, 해당 메서드를 실행함. AllViaServer, // 서버를 통해 모두에게 메서드를 전달함. AllBufferedViaServer // 서버를 통해 모두에게 메서드를 전달함. // 나중에 들어오는 클라이언트도 buffered 되었기 때문에, 해당 메서드를 실행함. }
4. PhotonNetwork
: 멀티플레이어 게임을 구현하기 위한 네트워킹 및 통신을 담당함.
A. 네트워크 연결 관리
PhotonNetwork.ConnectToMaster()
: 포톤 마스터 서버로 연결.
- 파라미터
string (마스터 서버의 주소)
int (Port)
string (appID)- 반환 값
: bool
PhotonNetwork.DisConnect()
: 포톤 서버와 연결 해제
- 반환 값
: bool
PhotonNetwork.Reconnect()
: 마스터 서버로 다시 연결
- 반환 값
: bool
ReconnectAndRejoin()
: 게임 중, 연결이 끊긴 클라이언트로 하여금 재접속을 도와줌.
- 반환 값
: bool
B. 네트워크 오브젝트 관리
PhotonNetwork.Instantiate()
: 네트워크 오브젝트 인스턴스화 및 생성
- 파라미터
GameObject (게임 오브젝트)
PhotonNetwork.Destroy()
: 네트워크 오브젝트 파괴
- 파라미터
GameObject (게임 오브젝트)
PhotonNetwork.FindGameObjectsWithComponent()
: 지정한 타입의 컴포넌트를 지닌 오브젝트 탐색
- 파라미터
Type (컴포넌트 타입)
- 반환 값
: HashSet<GameObject>
PhotonNetwork.LoadLevel()
: 플레이어로 하여금 같은 씬으로 전환되게 함.
- 파라미터
string (씬의 이름) / int (씬의 번호)
C. 플레이어 관리
PhotonNetwork.LocalPlayer
: 로컬 플레이어(클라이언트 본인의 플레이어)를 참조.
: 커스텀 프로퍼티를 활용해, 사용자 지정 플레이어 속성 혹은 이름을 설정할 때 유용.
Player LocalPlayer
PhotonNetwork.MasterClient
: 현재 룸의 마스터 클라이언트를 참조.
Player MasterClient
PhotonNetwork.SetMasterClient()
: 현재 룸에서 다른 플레이어를 마스터 클라이언트(호스트)로 변경하는 것을 서버에 요청.
- 파라미터
Player (마스터 클라이언트로 삼을 플레이어)
- 반환 값
: bool
PhotonNetwork.PlayerList
: 현재 룸의 플레이어들의 리스트. 각 요소는 각각의 플레이어를 참조함.
Player[] PlayerList
D. 룸 관리
PhotonNetwork.JoinLobby()
: 마스터 서버에 연결되어 있다면, 로비에 참가하여, 참가 가능한 방의 리스트를 얻을 수 있음. :
public static bool JoinLobby(TypedLobby typedLobby) { if (PhotonNetwork.IsConnected && PhotonNetwork.Server == ServerConnection.MasterServer) { return NetworkingClient.OpJoinLobby(typedLobby); } return false; }
- 파라미터
TypedLobby (로비의 형식)
: 로비의 형식은 로비의 이름, 사전에 지정한 타입에 따라 정해짐.
public enum LobbyType :byte { Default = 0, SqlLobby = 2, AsyncRandomLobby = 3 }
- 반환 값
: bool
PhotonNetwork.JoinRoom()
: 파라미터로 입력받은 방 이름을 통해 방에 참가함.
- 파라미터
string (방 이름)
string[] (예상되는 유저)- 반환 값
: bool
'Unity' 카테고리의 다른 글
Photon - 동기화에 대한 이해 (1) (1) 2023.11.06 photon - 채팅 기능 구현 기획 (0) 2023.10.26 Photon - Demo 탐색 (0) 2023.10.25 네트워크 게임의 이해 (0) 2023.10.24 readme 작성 (0) 2023.10.19