Unity | Photon View, RPC

Clean·2025년 7월 14일

Unity

목록 보기
19/24

오늘 한 것

  • MonoBehaviourPun 상속

  • 게임 오브젝트 동기화 Photon View

  • 네트워크 생성 및 삭제

  • 원격 함수 호출 RPC

  • 방장 변경 이벤트 처리 (OnMasterClientSwitched)

  • 채팅 기능 구현


MonoBehaviourPun 상속

MonoBehaviourPun 클래스는 MonoBehaviour를 상속받고 있고
이 게임오브젝트에 있는 PhotonView를 찾고 캐싱해두는 클래스


게임 오브젝트 동기화 Photon View

Photon View는 네트워크에서 동기화가 필요한 오브젝트에 추가하여
오브젝트의 소유권, 상태 동기화, RPC 연결 등의 역할을 하는 컴포넌트

  • View ID : 서버에서 오브젝트를 식별할 수 있는 고유 ID

  • IsMine : 해당 Photon View를 내 클라이언트가 소유한 오브젝트인지 여부

  • Observables : IPunObservable 인터페이스를 구현한 컴포넌트 목록

  • Observed Components : 동기화할 컴포넌트 리스트


Photon View 컴포넌트들

  • Photon Transform View : position, rotation, scale 동기화
  • Photon Rigidbody View : Rigidbody의 위치, 회전 동기화
  • Photon Animator View : Animator 파라미터 동기화

그 외로 UI View들도 있음

Friend List View
Player List View
Room List View
Player Overview Panel
Region List View
Tab View Manager


변수 동기화 IPunObservable

동기화할 컴포넌트에 IPunObservable 인터페이스를 추가 후, OnPhotonSerializeView 를 구현해야함

// 게임 오브젝트 위치 동기화
if (stream.IsWriting)
{
	stream.SendNext(transform.position);
	stream.SendNext(_moveSpeed);
}
else if (stream.IsReading)
{
	_networkPosition = (Vector3)stream.ReceiveNext();
	_moveSpeed = (float)stream.ReceiveNext();
}

ex) bool, byte, short, int, long, float, double, string, Vector2, Vector3, Quaternion, Player(int PhotonPlayer.ID)

  • stream.SendNext()값 타입만 전송 가능

  • stream.ReceiveNext() 데이터를 받을 때는 보낸 순서대로 받고, 형변환을 해야함

  • stream.IsWriting 은 내가 데이터를 보낼 때

  • stream.IsReading 은 다른 클라이언트의 데이터를 받을 때

  • 그 외의 데이터는 RPC로 보내야 함


게임 오브젝트는 각 클라이언트마다 메모리 주소가 다르기 때문에 전송할 수 없다.
대신, 모든 클라이언트에서 동일한 값을 가지는 ViewID 를 전송하여 오브젝트를 식별할 수 있다.

int id = photonView.ViewID;
보내는 쪽에서 객체 대신 ID를 전송하고

PhotonView target = PhotonView.Find(id);
받는 쪽에서 ID로 객체를 찾는 방식이다.


네트워크 생성 및 삭제

생성

기존의 Instantiate() 가 아닌 PhotonNetwork.Instantiate() 를 사용해야함

PhotonNetwork.Instantiate("프리팹 이름", new Vector3(0, 0, 0), Quaternion.identity);

프리팹 이름은 Resources 폴더에 있는 프리팹 이름을 뜻한다.

  • 누구나 호출 가능함

RoomObject 생성

룸에 상주하고 있는 오브젝트는

PhotonNetwork.InstantiateRoomObject("프리팹 이름", new Vector3(0, 0, 0), Quaternion.identity);

를 사용하여 인스턴스화해야 한다.

  • 방장 클라이언트에서만 호출할 수 있음

  • 새로 입장한 유저들도 자동으로 인식

  • 룸에 남아 있는 동안 유지됨


삭제

PhotonNetwork.Destroy(photonView);

PhotonView 컴포넌트를 기준으로 오브젝트를 파괴하고,
PhotonNetwork.Instantiate() 로 생성된 오브젝트만 파괴할 수 있다.


원격 함수 호출 RPC

RPCPhoton View가 있는 오브젝트에 네트워크를 통해 함수를 실행시킬 수 있는 기능

photonView.RPC("Shoot", RpcTarget.AllBufferedViaServer);

[PunRPC]
public void Shoot(PhotonMessageInfo info)
{
	float lag = Mathf.Abs((float)(PhotonNetwork.Time - info.SentServerTime));
	Debug.Log($"서버 시간 - 보낸 서버 시간 = {lag}");
	GameObject newBullet = Instantiate(_bulletPrefab, _muzzlePoint.position, _muzzlePoint.rotation);
	newBullet.GetComponent<Bullet>().ApplyLagCompensation(lag);
}

RPC("함수명", RpcTarget.실행할 대상들, 매개변수~)

  • 실행할 함수는 public 이어야 하며, [PunRPC] 어트리뷰트를 추가해야 함

  • RpcTarget

이름대상
All자신 포함 모든 클라이언트에 전송
Others자신 제외 모든 클라이언트에 전송
MasterClient방장 클라이언트에 전송
AllBufferedAll과 같지만 호출을 누적, 새로 입장한 클라이언트에 순차적 전송
OthersBufferedOthers와 같지만 호출을 누적, 새로 입장한 클라이언트에 순차적 전송
AllViaServer자신 포함 모든 클라이언트에게 서버를 경유하여 전송
AllBufferedViaServerAllViaServer + Buffered
  • 실행할 함수에 PhotonMessageInfo 매개변수를 추가하여 보낸 플레이어, 보낸 서버 시간 등을 알 수 있음

  • 매개변수는 직렬화 가능한 타입만 보낼 수 있음

  • 쌓인 Buffered 함수들은 PhotonNetwork.RemoveBufferedRPCs(); 로 지울 수 있다.

    • 매개변수로 특정 Photon View, 함수, 플레이어가 호출한 RPC만 제거할 수 있다.

0개의 댓글