일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- Unity
- Design
- JPS
- 머신러닝
- 인공지능
- 문제풀이
- Factory
- A*
- ML Agent
- 성능
- 알고리즘
- 길 찾기
- 디자인 패턴
- 강의
- 디자인패턴
- 패턴
- desgin
- 디자인
- 게임
- 팩토리
- LeetCode
- Algorithm
- GetComponet
- C++
- 개발
- pattern
- 프로그래밍
- 유니티
- AI
- 2번
- Today
- Total
Game Development
유니티 포톤 데이터 전송 속도 개선 하기 본문
유니티 포톤 RPC 전송 속도
Photon이란 무료로 멀티 게임을 만들 수 있게 지원해주는 플렛폼이라고 생각하시면 됩니다.
Photon에서 타 유저의 함수를 실행시킬때 사용하는 [PunRPC] 태그에 대해서 알아보도록 하겠습니다.
[PunRPC] 해당 태그는 RPC라는 함수를 통해 호출을 합니다. Photon Network를 기반으로 개발하면
느린 반응속도에 대해서 불만은 가지시는 분들이 많을 껍니다.
이러한 부분을 개선할 수 있는 방법을 소개해드릴려고 합니다
RPC
특정 함수를 양쪽에서 같이 호출하기 위해서 RPC라는 함수를 사용하게 됩니다.
이 RPC라는 함수를 호출 시 바로 패킷을 보내는 녀석이 아니라 버퍼에 따로 담아 뒀다 오브젝트에 변화가 있을 때 같이 보냅니다.
[ 속도 개선 방법 ]
속도를 개선하는 방법은 Photon 사이트 에 친절하게 설명이 되어 있고, 다음과 같습니다.
1. RPC 태그가 붙은 함수이름을 짧게 한다.
[PunRPC]
public void PlayerMoveAndRotationSetRPC() { }
이런식으로 긴 이름의 함수를 가진것이 아니라 아래처럼 짧은 이름을 가진 함수를 사용하는것이 효율적 입니다.
[PunRPC]
public void UpdateTransform() { }
이유는 간단합니다. 문자열은 네트워크를 통한 전송에서 가장 비효율 적이기 때문입니다. 그렇기에 포톤에서는 해당 함수 문자열을 줄여서 보내는 트릭을 사용하게 됩니다. 그렇기에 저희가 함수이름을 짧게 짓어서 사용하는것이 좋습니다.
2. RPC 호출 후 바로 패킷 보내기
RPC는 호출 시 바로 패킷을 전송하는것이 아니라 버퍼에 담아뒀다 오브젝트의 변화가 있을 때, 전송을 합니다.
그렇기 떄문에 해당 RPC를 바로 보내고 싶을 경우 다음과 같은 함수를 사용하게 됩니다.
PhotonNetwork.SendAllOutgoingCommands();
해당 함수를 호출하게 된다면 RPC로 실행하고 버퍼에 담긴 함수를 강제로 실행할 수 있습니다.
패킷을 계속 보내게 된다면 결국 속도는 느려지게 될것이니 적절한 타이밍에 사용하는것이 좋을거 같습니다.
3. 패킷 전송을 줄여보자
당연한 말이지만 지연 속도를 줄이기 위해 패킷 보내는 양을 줄이면 됩니다.
예시를 들자면 총알이 날라가는 위치를 계속 동기화를 하는것이 아닌 처음에 총알의 스폰위치와 방향만 RPC로 전송해 주고, 나머진 클라이언트에서 처리하게 하는씩으로 하여 패킷 전송을 최소화할 수 있습니다.
[ 나만의 패킷을 만들기 ]
오브젝트의 위치를 동기화 하기 위해 Photon Transfrom View라는 컨퍼넌트를 장착하게 됩니다.
이것보다 더욱 빠른 방법으로 위치 및 자신이 원하는 데이터를 전송하는 방법을 알려드리겠습니다.
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) { }
해당 함수를 사용하기 위해선 클래스에 IPunObservable를 상속하여 사용해야 합니다.
1. 패킷을 보낼 것인지, 받을 것인지 확인하는 법
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if ( stream.IsWriting )
{
}
else if ( stream.IsReading )
{
}
}
stream 매개변수를 통하여 현재 값을 쓸수 있는지 아니면 패킷이 왔는지를 확인할 수 있습니다.
2. 패킷을 보내는 방법과 받는 방법
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if ( stream.IsWriting )
{
stream.SendNext( _object );
stream.SendNext( _object );
}
else if ( stream.IsReading )
{
stream.ReceiveNext( );
stream.ReceiveNext( );
}
}
값을 보내는 방법은 간단합니다. SendNext 함수와 ReceiveNext를통해 값을 전달 및 받을 수 있습니다.
만약 Position과 Rotation을 전송하고 싶다면 아래와 같이 하면됩니다.
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if ( stream.IsWriting )
{
stream.SendNext( transform.position );
stream.SendNext( transform.rotation );
}
else if ( stream.IsReading )
{
nextPos = ( Vector3 )stream.ReceiveNext( );
nextRotation = ( Quaternion )stream.ReceiveNext( );
}
}
보내는 데이터에 맞춰 받는 순서를 똑같이 해주면 됩니다.
이렇게 데이터를 보내고 받게 되면 아래와 같이 움직이게 됩니다.
살짝 끊기는느낌이 듭니다. 이유는 간단한데요. 포톤에서 패킷은 1초에 10번 전송하기 때문입니다.
그래서 포톤에서 값을 받아온 후 클라이언트에서 보정을 해야하는 작업이 필요해집니다.
마무리
Photon 사이트에서도 한글화된 문서를 통해 최적화 방법을 알 수 있습니다.