기능 개요
호스팅
Cloud 또는 OnPremises
PUN 클라이언트는 Photon Cloud 또는 자신의 Photon Server에 연결합니다.
나만의 서버를 호스팅할 계획이라도 Photon Cloud에서 시작해보는 것도 좋습니다.
최적 지역
Photon Cloud는 플레이어를 분산시키고 대기 시간을 낮게 유지하기 위해 전세계의 많은 지역에서 호스팅됩니다.
PUN 클라이언트는 사용 할 수 있는 서버를 동적으로 확인하고 최상의 서버를 자동으로 선택합니다.
지연 시간이 더 이상 나빠지지 않는 한 클라이언트는 해당 지역을 고수할 것입니다.
연결할 때 지역 목록이 변경되면 PUN은 완전히 자동으로 모든 지역을 다시 평가할 것 입니다.
"최적 지역" 옵션은 결정론적이지 않습니다.
때로는 약간의 변동성 또는 정확히 동일한 핑 계산으로 인해 "무작위" 일 수 있습니다.
이론적으로 가능한 것:
- 동일한 기기에서 여러 영역으로 동일한 핑 값을 가진 경우입니다. 따라서 동일한 네트워크에 연결된 클라이언트는 무작위로 다른 지역에 연결됩니다.
- 동일 네트워크에 연결된 서로 다른 기기에서 동일한 지역에 대하여 서로 다른 핑 값(또는 동일한 기기에서 다른 시도)
예를 들어, "us" 그리고 "usw"인 경우(또는 "ru" 그리고 "rue")에, 원하는 지역을 선택 또는 나머지 지역을 없앨 수 있도록 온라인 지역 화이트리스트를 사용할 수 있거나 지역을 지정하여 접속할 수 있습니다.
Udp, Tcp 와 WebSockets
PUN은 여러개의 전송 레이어 프로토콜을 지원하므로 대부분의 플랫폼들과 호환됩니다.
기본 프로토콜은 안정한 프로토콜 기반의 UDP입니다.
이 프로토콜은 빠르며 유연합니다.
스펙트럼의 다른 편에 있는 WebSockets는 일부 플랫폼에서 유일하게 지원되는 프로토콜로써 사용됩니다(예: WebGL 내보내기).
일반사항
Unity 통합
PUN은 Unity와 아주 밀접하게 통합됩니다.
에디터를 확장하고 인스펙터를 사용하고 PhotonView 컴포넌트를 제공하여 게임 객체를 쉽게 네트워크로 연결할 수 있도록 합니다.
GameVersion에 의한 버전관리
Photon Cloud에서는 AppId를 변경하지 않고, 각각의 빌드(그리고 플레이어)를 분리하기 위한 간단한 방식으로 GameVersion 문자열을 사용합니다.
네트워크 로직이 많이 변경될 때에는 GameVersion을 변경하여 다른 버전의 플레이어를 구분합니다.
인증
Photon은 게임 타이틀에서 사용해야 하는 커뮤니티 백엔드를 통합하기 위해 아주 간단한 REST API를 사용합니다.
외부 인증을 사용하여 사용자 계정을 이용할 수 있으며 사용자의 ID 및 임의 값을 얻어올 수 있습니다.
필요한 경우 사용자가 연결할 수 없도록 차단할 수도 있습니다.
콜백
PhotonNetwork
는 "연결됨" 또는 "게임에 참여함" 과 같은 상태 변화에 대한 것을 인지하기 위한 몇 개의 콜백을 제공합니다.
PUN 2에서는 인터페이스(성능상의 이유로 인해)로 콜백을 구성하고 이러한 인터페이스를 구현하는 모든 클래스는 PhotonNetwork.AddCallbackTarget()
을 통해 등록되어야 합니다.
또한, 스크립트에서 각 콜백 메소드를 개별적으로 재정의할 수 있는 MonoBehaviourPunCallbacks
를 확장하여 작성할 수 있습니다.
이 경우에는 기본 구현을 호출할 필요는 없습니다.
C#
public class MyClass : MonoBehaviourPunCallbacks
{
//...
public override void OnJoinedRoom()
{
Debug.Log(string.Format("OnJoinedRoom() called by PUN: {0}", PhotonNetwork.CurrentRoom.Name));
}
매치메이킹
무작위 매치메이킹
Photon의 매치메이킹 접근법은 클라이언트 기반이며 유연합니다. 전형적으로, 서버는 적당하고 클라이언트에서 요청한 무작위 룸을 PhotonNetwork.JoinRandomRoom()
를 통해 선택합니다.
다양한 필터링 옵션은 선택범위를 좁히기 위해 사용될 수 있습니다.
매치메이킹에 대한 상세사항은 "매치메이킹 지침"를 참고하십시오.
로비와 룸 목록
로비는 여러개의 목록으로 룸을 구성시킬 수 있습니다.
클라이언트는 리스트를 얻고 갱신하기 위해 로비에 참여할 수 있습니다. "SQL Lobby"라고 하는 이것은 매우 유연한 "WHERE" 필터링을 통한 쿼리를 지원합니다.
또한, 클라이언트는 사전에 필터링된 선택 사항을 표시하기 위해 목록의 하위 집합에 대하여 서버에게 질의할 수 있습니다.
룸 옵션
클라이언트는 룸을 생성할 때 새로운 룸의 일부 동작 방식을 정의할 수 있습니다.
물론 플레이어의 최대 수를 정의할 수 있습니다.
룸을 보이지 않게 설정하면 해당 룸은 매치메이킹에서 제외되며, 해당 룸 이름을 알 고 있는 사용자만이 참여할 수 있습니다.
플레이어의 userID를 공유할 수 있으며, 연결이 끊긴 후 플레이어의 ID가 사용자가 룸 목록에 남아 있는지에 대한 시간 등을 정의합니다.
매치메이킹을 위한 사용자정의 속성
룸의 사용자정의 속성은 나만의 값 집합을 정의하고 공유하는데 사용할 수 있습니다.
키와 값들이 해시테이블을 통해 설정됩니다.
게임내에서 사용될 수도 있으며 매치메이킹에서도 사용될 수 있습니다.
어떤 속성의 키들이 매치메이킹에서 사용할 수 있는지 정의만 하면 됩니다.
슬롯 예약
팀 또는 단체로 게임을 플레이 할 때, 플레이어들을 고정하여 같이 하고 싶을 수 있습니다.
Photon은 "예상되는 플레이어"를 통해 이 기능을 지원합니다:
목록에 있는 사용자들이 룸에 참여할 것 입니다.
Photon의 매치메이킹은 "예상되는" 플레이어 마다 슬롯을 예약합니다.
인게임
네트워크 객체
일반 GameObject들은 PhotonView 컴포넌트가 있는 네트워크 객체로 전환될 수 있습니다.
PhotonView는 네트워크를 통해 객체를 식별하고 해당 객체의 상태를 동기화하는 데 사용됩니다.
일반적으로, PhotonView는 런타임에 인스턴스화된 프리팹에 연결됩니다.
종종 모든 선수들은 통제할 자신만의 객체들을 가지고 있습니다.
GameObject에 PhotonView를 추가하기위해서는, 단순히 GameObject를 선택하고 사용하면 됩니다:"Components/Miscellaneous/Photon View"
메시지
룸에 들어가 있으면, 클라이언트는 다른 플레이어나 선택한 플레이어들에게 메시지를 전송할 수 있습니다.
"저 수준" 일반 이벤트와는 별도로(참조:RaiseEvent
), PUN에는 두 개의 메시지 기능을 가지고 있습니다:
RPC는 메소드 호출로써 특정한 네트워크 객체상에서 모든 플레이어들에 의해 실행되고 두 번째는 PhotonView로 이 객체의 값(위치, 체력 등)을 동기화 하기위해 스크립트를 관찰할 수 있습니다.
관찰되는 스크립트는 OnSerializePhotonView
를 구현해야 합니다.
필요한 경우 메시지를 서버에서 버퍼링할 수 있으며, 이 버퍼링으로 인해 나중에 참가하게 되는 플레이어에게도 메시지가 전송됩니다.
예를 들면 캐릭터를 스폰하는 데 사용됩니다.
Mecanim (Animator) 동기화
PUN은 캐릭터의 애니메이션 상태를 자동으로 동기화하는 컴포넌트를 제공합니다.
동기화된 타임스탬프
클라이언트가 Photon Server에 연결할 때마다 지연된 타임스탬프가 동기화할 것 입니다.
이 기능은 룸에서 이벤트 타이밍을 동기화하는 데 사용할 수 있습니다(모든 플레이어가 동일 게임 서버에 연결되므로).
사용자정의 속성
Photon Realtime의 사용자정의 속성은 임의의 값을 동기화하는 방법입니다.
사용자정의 속성들은 간단하게 해시테이블에 구성되어 있으며 룸이나 개별 플레이어와 관련되어 있습니다.
고급 인게임
비교하고 스왑(Compare-And-Swap, CAS)
누구나 사용자정의 속성을 설정할 수 있으므로 게임 로직은 동시성 문제가 발생할 수 있습니다.
이 문제는 CAS로 해결할 수 있습니다: 서버의 현재 값이 조건과 일치하는 경우에만 새로운 값이 설정됩니다.
요약: 모든 사용자가 서버에게 "1에서 X"로 값을 변경하라고 할 때 이 작업은 한 번만 발생됩니다.
Scene PhotonViews
기본적으로 네트워크 객체는 해당 객체를 인스턴스한 플레이어와 동일한 라이프사이클을 가집니다.
플레이어가 떠나면 객체가 사라집니다.
Scene PhotonViews는 씬을 로드한 후 인스턴스화될 수 있지만, 존재하고 있는 룸 내에서만 있게됩니다.
물론 씬과 함께 로드된 네트워크 개체는 플레이어의 라이프사이클과는 관계가 없습니다.
객체-제어 이전
기본적으로 네트워크 객체는 인스턴스화를 한 클라이언트에 의해 제어됩니다.
오너십 이전으로 플레이어는 게임 오브젝트의 제어권을 요청하거나 양도할 수 있습니다.
이렇게 하면 업데이트를 보내는 클라이언트가 변경됩니다(다른 사용자가 사용하고 적용하는 동안).
관심 그룹
Photon Realime(PUN에 의해 싸여진)의 관심 그룹은 클라이언트가 받는 이벤트를 구성할 수 있습니다.
로직을 기반으로하여, 클라이언트는 그룹에 가입하고 대상 그룹에 이벤트를 전송합니다.
이것은 기본적인 관심 관리 시스템에서 사용될 수 있다.
사용자정의 타입 직렬화
Photon을 사용하여 네트워크를 통해 보내고자 하는 모든 유형에 대해 직렬화/비직렬화 코드를 정의할 수 있습니다.
이 기능은 네트워크를 통해 데이터를 전송하는 방법이 매우 간단하게 해줍니다(오버헤드 비용 절감).
WebHooks 그리고 데이터 보관 전략
Photon Server와 다른 서비스 및 사용자 서비스를 연결하기 위해서 WebHooks의 개념을 이용합니다.
여러 개의 후크가 사전 정의되어 있으며 외부 REST 기반 서비스를 업데이트하는 데 사용할 수 있습니다.
턴기반 게임
룸은 턴 기반 게임에 대해서는 두 가지 옵션이 중요합니다:
PlayerTTL은 연결이 끊긴 후 참가자가 룸에서 "비활성" 상태를 유지하는 시간을 정의합니다.
RoomTTL은 룸의 모든 플레이어들의 연결이 끊긴 이후 룸이 존재하는 기간을 정의합니다.
이렇게 하면 재참여하는 플레이어들을 위해 룸과 플레이어스팟을 유지할 수 있습니다.
성능 옵션
Pooling 지원
PUN을 사용하여 인스턴스화되고 파괴되는 모든 네트워크 개체에 대해 간단한 풀 구현을 사용할 수 있습니다.
일부 유형의 게임에서는 일반적이지는 않지만, 다른 게임에서는 성능을 증가 시킬 수 있습니다.
캐싱
풀을 사용하는 대신, PUN은 프리팹(네트워크화된 객체로)을 인스턴스화 하기 위해 로드되는 리소스를 캐시할 수 있습니다.
이 기능은 가비지 콜렉션을 감소시켜 메모리 비용을 줄여줍니다.
SendRate/SendRateOnSerialize
PUN은 네트워크 개체에서 업데이트 쓰기(그리고 읽기) 속도를 제어합니다.
메시지를 넣어 어떤 업데이트에 보낼지에 대한 속도는, 독립적으로 설정할 수 있습니다.