[Unity] Photon RPC 동기화

limce·2025년 4월 20일

Unity

목록 보기
5/6
post-thumbnail

PunRPC

포톤은 Pun, Realtime 등 여러 서비스를 제공하는데, 그 중 PUN은 원격 프로시저 호출(Remote Procedure Call, RPC)을 지원한다.

프로시저

  • 루틴이나 서브루틴 및 함수와 같은 뜻이다.
  • 어떤 행동을 수행하기 위한 일련의 작업순서

원격 프로시저 호출

  • 원격제어를 통해 함수나 프로시저의 실행을 허용하는 기술
  • 예시: 윈도우 인증, SMS 서버 등
  • 게임에서는 같은 룸에 있는 다른 유저(클라이언트)의 메서드를 호출하는 것이다.

PhotonView

  • 포톤 네트워크에서 데이터를 동기화하기 위해서는 PhotonView라는 컴포넌트가 반드시 필요하다.
  • 네트워크 객체의 식별자 역할을 한다.
  • RPC()는 이 photonView에 종속된 객체에서 실행된다.

ViewID

  • 네트워크 상에서 오브젝트를 고유하게 식별하는 ID

Observed Components

  • 동기화할 컴포넌트들(Transform, Rigidbody 등)을 지정
  • 현재까지는 이 오브젝트에 Observed Component가 필요하지 않아 None 상태이지만, 플레이어에게 부착된 경우 Photon Transform View, Photon Animator View가 추가될 수 있다.
    (추후 구현 완료 시 링크 첨부할 예정)

Ownership

  • 누가 이 오브젝트의 소유자인지 판단 (마스터 클라이언트, 로컬 클라이언트 등)
  • Fixed: 고정
  • Takeover: 주인에게 허락 받아야 가져갈 수 있다.

Syncronization

  • Off: RPC만 사용할 경우
  • Reliable Delta Compressed: 받은 데이터를 비교해 같으면 보내지 않는다.
  • Unreliable: 계속 보낸다. 손실 가능성이 있고 무겁다.
  • Unreliable On Change: 변경이 있을 때 계속 보낸다.

*Off 이외에는 모두 Observed Components에 Component가 하나라도 있어야 한다.
(해당 오브젝트는 추후 컴포넌트가 추가될 가능성이 있어, None임에도 Off로 설정하지 않았다.)

Photon RPC 함수를 사용하는 방법

  • 메서드에 대해 원격 호출을 사용하려면 [PunRPC]를 사용해야 한다. (함수 내용은 이해하려고 할지 말고 [PunRPC]를 사용해야 한다는 점만 기억해두자.)
  • [PunRPC]를 사용하는 메서드는 네트워크 상의 다른 클라이언트들에 의해 호출될 수 있다.
  • 네트워크에서 메서드를 호출하려면 PhotonView 컴포넌트를 통해 메서드를 호출해야 한다.
  • RPC 메서드를 사용하기 위해서는 Photon View Component가 부착된 오브젝트에 해당 메서드가 선언된 클래스가 같이 부착되어 있어야 한다.
  • RPC 메서드를 사용하기 위해서는 Photon View Component가 부착된 오브젝트에 해당 메서드가 선언된 클래스가 같이 부착되어 있어야 한다. Git 등 협업 툴을 이용할 경우 RPC Method의 이름이 에셋에 저장되있지 않다면 에러가 발생한다. (Assets > Photon > PhotonUnityNetworking > Resources > PhotonServerSettings)

RPC 함수 호출

// 다음 글에 나오겠지만, PV는 photonView이다.
photonView.RPC("MarkReady", RpcTarget.MasterClient, PhotonNetwork.LocalPlayer.ActorNumber);
  • photonView.RPC("함수명", RPC 함수 타겟, 호출하려는 함수의 파라미터 값)

RpcTarget

  1. RpcTarget.All
    • 모든 클라이언트에게 실행된다.
    • 나를 포함한 모든 클라이언트가 실행하게 된다.
  2. RpcTarget.Others
    • 호출한 클라이언트(나)를 제외한 나머지 클라이언트에게만 실행된다.
  3. RpcTarget.MasterClient
    • 현재 방장에게만 실행된다.
  4. RpcTarget.AllBuffered
    • All과 같지만, 나중에 들어오는 클라이언트도 실행된다.
    • Photon이 이 RPC를 버퍼에 저장해 두고, 방에 새로 들어온 사람에게도 자동으로 호출해준다.
  5. RpcTarget.OthersBuffered
    • 나를 제외한 모두 + 버퍼에 저장된다.
    • llBuffered 거의 같지만, 호출자는 제외된다.
  6. RpcTarget.AllViaServer
    • All과 비슷하지만, 모든 호출이 무조건 서버를 통해 전달된다.
    • 클라이언트 간 직접 호출이 아니라, 항상 중간에 서버를 거친다.
  7. RpcTarget.AllBufferedViaServer
    • AllBuffered + ViaServer
    • 모든 클라이언트 + 버퍼 저장 + 서버 경유

*Buffered 키워드가 붙은 Target은 너무 많이 사용할 경우 속도 저하의 위험성이 존재한다.

마스터 클라이언트(Master Client)

마스터 클라이언트는 Photon 방에서 자동으로 지정되는 방장 역할을 하는 클라이언트이다. 처음 방에 들어온 클라이언트로, 마스터가 나가면 자동으로 다른 클라이언트에게 권한이 넘어간다.

현재 코드는?

그럼 만약 MarkReady를 마스터가 아닌 일반 클라이언트가 실행하면?
RpcTarget.MasterClient이기 때문에 해당 RPC는 오직 현재 마스터 클라이언트만 실행하게 되고, 호출한 클라이언트 자신은 이 함수를 실행하지 않는다.

이해를 돕기 위해, MarkReady RPC 함수가 Debug.Log("MarkReady");를 호출하는 함수라고 가정하자.

  1. 마스터 클라이언트가 호출했을 때
  • 마스터만 실행한다.
  • 마스터의 콘솔에만 "MarkReady"가 출력된다.
  1. 마스터가 아닌 일반 클라이언트가 호출했을 때
  • 1번과 동일
  • 마스터만 실행한다.
  • 마스터의 콘솔에만 "MarkReady"가 출력된다.
  1. 만약 타깃이 All 이라면
  • 누가 호출하든, 모든 클라이언트가 실행
  • 마스터를 포함한 모든 클라이언트의 콘솔에 "MarkReady"가 출력된다.



멀티 플레이와 네트워크를 활용한 프로젝트가 처음이고 공부할 시간없이 바로 시작하다 보니, 처음 RPC 함수를 공부할 때 타깃과 그에 따른 실행이 어떻게 되는건지 헷갈렸다. 타깃이 MasterClient일 때 RPC 함수를 일반 클라이언트가 호출하면 아무 일도 안 일어나는 것인지, 호출이 된다면 어떤 식으로, 몇 번 되는 것인지 헷갈렸는데 이렇게 디버깅 코드만 출력하는 함수를 만들어 테스트 해보니 이해가 쉬웠다.
이 글만으로 RpcTarget과 그에 따른 결과가 헷갈린다면 직접 엔진을 켜서 디버깅 코드를 실행해보길 추천한다.

포톤 데이터 전송 속도 개선하기

  1. RPC 태그가 붙은 함수 이름은 짧게
  • 문자열은 네트워크를 통한 전송에서 가장 비효율적이기 때문이다.
  1. RPC 호출 후 바로 패킷 보내기
  • RPC는 호출 시 바로 패킷을 전송하지 않고, 버퍼에 담아뒀다 오브젝트의 변화가 있을 때 전송한다. 따라서 해당 패킷을 보내고 싶을 때는 아래와 같은 함수를 사용한다.
PhotonNetwork.SendAllOutgoingCommands();

해당 함수를 호출하면 버퍼에 담긴 함수를 강제로 실행할 수 있다.
패킷을 계속 보내면 속도가 느려지므로 적절히 사용하는 것이 좋다.

  1. 패킷 전송을 줄여보자
  • 당연하지만 지연 속도를 줄이고 싶으면 패킷 전송을 줄이면 된다.
  • 예를 들어, 총알이 날라가는 위치를 계속 동기화 하는 것이 아니라, 처음에 총알의 스폰 위치와 방향만 RPC로 전송해주고 나머진 클라이언트에서 처리하게 하는 식으로 패킷 전송을 최소화할 수 있다.




RPC 함수 적용 예시


참고
https://photonkr.tistory.com/22
https://game-dev.tistory.com/5
https://computer-art.tistory.com/entry/03-%ED%8F%AC%ED%86%A4%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EB%8F%99%EA%B8%B0%ED%99%94photonView-RPC-OnPhotonSeralize
https://memmaeranger.tistory.com/6

0개의 댓글