PUN Classic (also called PUN1) is the original and first major version of PUN. It is now replaced by PUN2 which is refactored and enhanced. We highly recommend starting new projects with PUN2 and if possible migrating existing ones from PUN1 to PUN2 by following our "Migration Notes". PUN Classic will be maintained for the coming months. We will fix important bugs and support new Unity versions but new features will be added only to PUN2.

Photon의 직렬화(Serialization)

Photon과 클라이언트는 통신할 때 고도로 최적화된 바이너리 프로토콜을 이용합니다. 바이너리 프로토콜은 컴팩트 하지만 해석하기 쉽습니다.

Photon은 데이터가 전송되기 전 바이너리 프로토콜로 변환 되어야 합니다. 일반적으로 널리 사용되는 데이터 타입에 대해서는 자동 변환 됩니다. 필요시 대부분의 클라이언트 API에서 특정 클래스들만의 직렬화(serialization) 방식을 등록 할 수 도 있습니다. 아래를 참고 해 보세요.

Photon 에서 지원하는 데이터 타입

다음의 타입들은 일반적으로 지원되는 것으로 Photon 의 바이너리 프로토콜에서 알고 있습니다.
특정 언어에서는 나열한 모든 타입을 지원하지는 않습니다. 일부 SDK 에서는 몇 가지 타입만 지원 합니다.

타입 (C#) 크기 [bytes] 설명
byte
2
8 bit unsigned
boolean
2
true or false
short
3
16 bit
int
5
32 bit
long
9
64 bit
float
5
32 bit
double
9
64 bit
string
3 + size( UTF8.GetBytes(string) )
< short.MaxValue length
byte-array
5 + 1 * length
< int.MaxValue length
int-array
5 + 4 * length
< int.MaxValue length
<type> 배열
4 + size(entries) - count(entries)
< short.MaxValue length
hashtable
3 + size(keys) + size(values)
< short.MaxValue pairs
dictionary
3 + size(keys) + size(values)
< short.MaxValue pairs
K- 또는 V-타입이 객체인 경우 추가적인 크기

Back To Top

Photon 유니티 네트워킹의 추가 타입

Photon 유니티 네트워킹(PUN)은 몇 개의 추가적인 타입을 지원 합니다. 추가적인 타입들은 "커스텀 타입"으로 구현되어 있으며 아래에 설명되어 있습니다.

Transform 과 PhotonView 는 이 목록에 없습니다. Transforms 은 "전체"로 설정될 수 없으므로 Position, Rotation과 Scacle 을 각각 전송 해야만 합니다. PhotonViews 는 일반적으로 viewId(줄여서) 에 의해 참조 됩니다. viewId 가 네트워크 게임에서 유일한 것으로 전송하는데 가장 부담이 없습니다.

타임 (C#) 크기 [bytes] 설명
Vector2 12 2 floats
Vector3 16 3 floats
Quaternion 20 4 floats
PhotonPlayer 8 integer PhotonPlayer.ID

Back To Top

커스텀 타입

위에서 열거되지 않은 타입에 대해서는 Photon을 위해 중요 값들을 직렬화/비직렬화 해주어야 합니다.

기본적인 개념은 두 개의 메소드를 통해 클래스를 byte-배열로 그리고 byte-배열을 클래스로 해주는 것을 구현 하는 것 입니다. 그리고 이 클래스를 Photon API 에 등록 합니다. 이 작업이 완료되면 이 타입에 대한 인스턴스를 모든 메세지에 포함하여 전송 할 수 있습니다.

Photon 은 등록된 타입에 대해서 직렬화 메소드를 호출 하고 자동적으로 생성된 byte-배열에 프리픽스를 붙여 줍니다. 이 프리픽스에는 타입 정보가 들어있고 4바이트 크기 입니다. 4바이트 오버헤드로 인하여 타입을 등록하는것을 원하지 않을 수 있는데 겨우 4바이트 입니다.

"현재" Photon 서버는 알수 없는 커스텀 타입을 포워드 할 수 있습니다. Photon 클라우드 내에서 타입을 등록하지 않았기 때문 입니다.

통신하는 모든 클라이언트에게 커스텀 타입이 등록 되었는지 확인 해주셔야 합니다.

Back To Top

C# 의 커스텀 타입

모든 C#-기반 API(.NET, Unity, Xamarin 등)는 동일한 등록 클래스를 제공 합니다.

등록 정적 메소드의 호출은 다음과 같습니다:

    PhotonPeer.RegisterType(Type customType, byte code, SerializeMethod serializeMethod, DeserializeMethod constructor)

SerializeMethod 와 DeserializeMethod 에는 위임자(delegate)가 정의됩니다:

    public delegate byte[] SerializeMethod(object customObject);
    public delegate object DeserializeMethod(byte[] serializedCustomObject);

Back To Top

예제

유니티의 Vector2 를 PUN 이 어떻게 구현하는지 살펴 보겠습니다.

Vector2 는 2개의 float 값을 가지고 있습니다: x 와 y 입니다. float 는 Photon 이 지원 하나 Vector2 는 지원 하지 않습니다.

SerializeMethod 에 결과적으로 바이트 배열이 필요 합니다. 기본적으로 float 와 유사한 4바이트를 받는 어떤 C# 방식을 사용해도 좋습니다. Photon 의 프로토콜 클래스는 효율적으로 몇개 데이터 타입을 바이트 배열로 써주는 몇 개의 Serialize 메소드가 있습니다.

    public static readonly byte[] memVector2 = new byte[2 * 4];
    private static short SerializeVector2(StreamBuffer outStream, object customobject)
    {
        Vector2 vo = (Vector2)customobject;
        lock (memVector2)
        {
            byte[] bytes = memVector2;
            int index = 0;
            Protocol.Serialize(vo.x, bytes, ref index);
            Protocol.Serialize(vo.y, bytes, ref index);
            outStream.Write(bytes, 0, 2 * 4);
        }

        return 2 * 4;
    }

SerializeVector2가 객체를 받아서 Vector2로 우선 캐스트(cast)해야 하는 것을 주의 하세요. 반대로 DeserializeVector2 에서는 객체만을 리턴 하게 됩니다:

    private static object DeserializeVector2(StreamBuffer inStream, short length)
    {
        Vector2 vo = new Vector2();
        lock (memVector2)
        {
            inStream.Read(memVector2, 0, 2 * 4);
            int index = 0;
            Protocol.Deserialize(out vo.x, memVector2, ref index);
            Protocol.Deserialize(out vo.y, memVector2, ref index);
        }

        return vo;
    }

마지막으로 Vector2를 등록 해야 합니다:

    PhotonPeer.RegisterType(typeof(Vector2), (byte)'W', SerializeVector2, DeserializeVector2);

To Document Top