동기화 방법
1. PhotonView
- 갱신이 빈번한 경우에 사용
- ex) 위치 이동, 상태 변경
- 캐릭터의 동기화에 사용 (PhotonView, PhotonTransformView 스크립트 추가)
Setting
Ownership
- Fixed : Ownership 고정
- Takeover : Ownership을 클라이언트가 가져갈 수 있음
- Request : Ownership을 클라이언트가 가졀갈 수 있지만, 주인에게 허락을 맡아야 함
Synchronization
- Off : RPC만 사용할 경우
- Reliable Delta Compressed : 받은 데이터를 비교해 같으면 보내지 않음
- Unreliable : 계속 보냄 (손실 가능성 있음)
- Unreliable On Change : 변경이 있을 때 계속 보냄
* Off 이외에는 모두 Observed Components에 Component가 하나라도 있어야 함
Observed Components
- 동기화 할 컴포넌트를 넣는 줌
- 변경된 값 중, 동기화 할 것을 관찰해서 다른 클론들에게 보내는 역할
객체 동기화
// PhotonView를 사용하여 플레이어를 생성하는 간단한 로직
private void OnJoinPlayer()
{
int index = UnityEngine.Random.Range(0, spawnPoints.Length);
PhotonNetwork.Instantiate("Player", spawnPoints[index].position, spawnPoints[index].rotation);
}
// 프리팹 파괴
PhotonNetwork.Destroy(gameObject);
* 반드시, 유니티 내장 Instantiate()가 아닌 해당 메소드를 사용해야 함!
* 프리팹은 Resources 폴더에 있어야 함!
* Room을 생성하거나, 참여한 뒤, 해당 메소드를 사용해야 함!
내가 생성한 객체 판단
private PhotonView _photonView;
// 플레이어 이동, 회전의 간단한 예제
private void Update()
{
if (!_photonView.IsMine)
return;
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
tr.Translate(Vector3.forward * v * Time.deltaTime * speed);
tr.Rotate(Vector3.up * h * Time.deltaTime * rotSpeed);
}
2. RPC
- 원격 프로시저 호출 (Remote Procedure call)
- 별도의 원격 제어를 위한 코딩 없이 다른 주소 공간에서 함수나 프로시저를 실행할 수 있게하는 프로세스 간 통신 기술
- 갱신이 드문 경우 사용
- 방에 있는 모든 Player에게 이 함수를 실행하도록 하는 의미
- 사용자가 직접 발생시키는 동기화
- PhotonView를 사용하지 않고 RPC를 사용하는 이유
- PhotonView는 많은 전송을 요구
- PhotonView를 통해 계속 동기화 대상을 늘리는 것은 좋은 방법은 아님
- ex) 총알의 동기화에 사용
- Lobby에서는 사용 불가, Room에서 사용
- 매개변수 전달 가능
- 객체를 들고 있는 RaycastHit, Collider 등은 전달할 수 없음
- int, vector3 등 전달 가능
- PhotonNetwork.Instantiate로 생성한 Player의 스크립트에서 실행해야 함
- PC1의 A Player (mine)의 RPC 실행 -> PC2의 A Player 함수 실행
- PC2의 B Player (mine)의 RPC 실행 -> PC2의 B Player 함수 실행
- 같은 Photonview 컴포넌트를 가지고 있는 Player의 함수 실행
- 다른 PC에서 행동을 제어 받아서 자신의 PC에서 실행하는 원리로 멀티 플레이
사용 예시
private void Update()
{
if (!_photonView.IsMine)
return;
bool fire = Input.GetMouseButton(0);
if (fire)
{
_photonView.RPC("Fire", RpcTarget.AllViaServer, rigidbody.position, rigidbody.rotation);
}
}
[PunRPC]
public void Fire(Vector3 position, Quaternion rotation, PhotonMessageInfo info)
{
float lag = (float)(PhotonNetwork.Time - info.SentServerTime);
GameObject bullet;
// 불릿 생성
bullet = Instantiate(BulletPrefab, gunOffset.position, Quaternion.identity) as GameObject;
// 불릿 초기화 로직
bullet.GetComponent<BulletCtrl>().InitializeBullet(photonView.Owner, (rotation * Vector3.forward), Mathf.Abs(lag));
}
- RpcTarget
- All : 이 클라이언트에서 즉시 실행하고, 방에 있는 모든 Player가 함수 실행
- AllBuffered : 이 클라이언트에서 즉시 실행하고, 방에 있는 모든 Player가 함수 실행. 새로운 Player는 이 클라이언트가 떠날때까지 함수 실행
- AllViaServer : 서버를 통해, 방에 있는 모든 Player(이 클라이언트 포함)가 순서대로 함수 실행
- Other : 이 클라이언트에서 실행하지 않고, 모든 Player가 함수 실행
멀티 플레이 코드를 싱글 플레이에 사용하는 방법
PhotonNetwork.OfflineMode = true;
오프라인 모드를 활성화 하면, 포톤으로 구현한 RPC 전송, PhotonNetwork.Instantiate 코드를 싱글 플레이 모드에서 똑같이 사용할 수 있다. PhotonNetwork.OfflineMode = false; 또는 서버 연결로 오프라인 모드를 중지할 수 있다.
호출 빈도 변경
PhotonNetwork.SendRate = 60; // 기본 설정 값 = 20
위 코드로 RPC의 초당 호출 빈도를 변경할 수 있다.
3. OnPhotonSerializeView
- PhotonView의 OnPhotonSerializeView 메서드를 사용하여 데이터를 전송, 수신
- IPunObservable 인터페이스를 추가해야 함
- 변수를 동기화할 때, 사용
- 1초에 10번 데이터 전송
스크립트 작성
// 인터페이스를 추가하고 이 함수를 추가해야 함
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
// 데이터 보내기 (isMine == true)
if(stream.IsWriting)
{
stream.SendNext(GameManager.I.DataManager.PlayerData.KoreaTag);
stream.SendNext(GameManager.I.DataManager.PlayerData.Level);
}
// 데이터 받기 (isMine == false)
else
{
_roomEnemyCharacterName = (string)stream.ReceiveNext();
_roomEnemyCharacterLevel = (int)stream.ReceiveNext();
}
}
* class 데이터는 전송할 수 없기때문에, int, string과 같은 변수를 전달해야 함!
Observed Components 추가
OnPhotonSerializeView 함수가 있는 스크립트를 추가
호출 빈도 변경
PhotonNetwork.SerializationRate = 60; // 기본 설정 값 = 10
위 코드로 OnPhotonSerializeView의 초당 호출 빈도를 변경할 수 있다.
'유니티 > PUN2' 카테고리의 다른 글
멀티 씬 이동 (1) | 2024.06.15 |
---|---|
Player 동기화 (PhotonTransformView, OnPhotonSerializeView , PhotonAnimatorView) (0) | 2024.06.13 |
채팅 구현 (0) | 2024.06.11 |
서버, 로비 접속 및 방 생성 (0) | 2024.06.06 |
PUN2 준비하기 (0) | 2024.06.04 |