Unity Photon

장현태입니다·2025년 7월 15일

Unity Photon

※ photon을 연습했던 내용이라 틀린 내용이 있을 수 있습니다

용어 정리

PhotonNetwork. + 

ConnectUsingSettings() 				// 접속 시도요청
Disconnect() 						// 접속 해제요청

CreateRoom("RoomName") 				// 방 생성 요청
JoinRoom("RoomName") 				// 방 입장 요청
LeaveRoom() 						// 방 퇴장 요청

JoinLobby() 						// 로비 입장 요청
LeaveLobby() 						// 로비 퇴장 요청

LoadLevel("SceneName") 				// 씬 전환 요청

(bool) IsConnected 					// 접속 여부 확인
(bool) InRoom 						// 방 입장 여부 확인
(bool) InLobby 						// 로비 입장 여부 확인
(ClientState) NetworkClientState 	// 클라이언트 상태 확인
(Player) LocalPlayer 				// 포톤 플레이어 상태 확인
(Room) CurrentRoom 					// 현재 방 정보 확인

오버라이드 함수 정리

OnConnected() 						  // 포톤 접속시 호출됨
OnConnectedToMaster() 				  // 마스터 서버 접속시 호출됨
OnDisconnected(DisconnectCause cause) // 접속 해제시 호출됨

OnCreateRoom() 						  // 방 생성시 호출됨
OnJoinedRoom() 						  // 방 입장시 호출됨
OnLeftRoom() 						  // 방 퇴장시 호출됨

OnPlayerEnteredRoom(Player newPlayer) // 새로운 플레이어가 방 입장시 호출됨
OnPlayerLeftRoom(Player otherPlayer)  // 다른 플레이어가 방 퇴장시 호출됨
OnCreateRoomFailed(short returnCode, string message) // 방 생성 실패시 호출
OnJoinRoomFailed(short returnCode, string message)   // 방 입장 실패시 호출

OnJoinedLobby() 						  // 로비 입장시 호출됨
OnLeftLobby() 							  // 로비 퇴장시 호출됨
OnroomListUpdate(List<RoomInfo> roomList) // 방목록 변경시 호출됨

Photon Pun에서 동기화 기법

  1. CustomProperty :

커스텀 프로퍼티는 포톤에서 제공하는 방의 이름, 최대 참여인원, 현재 참여인원등의 정보외에 추가적으로 프로그래머가 원하는 동기화를 하기위해 직접 선언해줄 수 있는 방법이다.
ExitGames.Client.Photon.HashTable 자료구조를 사용해서 사용가능

  1. PhotonView :

모든 오브젝트를 동기화시 비용이 막대하기 때문에 원하는 부분만 동기화를 진행하면 된다. 동기화가 진행 되어야하는 객체에 PhotonView를 적용하고 사용한다. 이 때 viewID를 통해 오브젝트와 상호작용 가능함
-> MonobehaviourPun을 사용하면 편하다 (photonView를 사용할 수 있기때문) +

  1. 생성, 삭제

모든 플레이어의 화면에 생성하고 삭제가 될 필요가 있는 오브젝트를 앞에 PhotonNetwork를 붙이는데 Instantiate("Resources폴더 안의 프리팹이름",위치,회전);을 기입해서 사용하면 된다.

PhotonNetwork.Instantiate("PrefabName",position,rotation);

PhotonNetwork.Destroy(photonView);

  1. 변수 동기화

데이터(변수)를 보내고 받는 형식의 IPunObservable - 인터페이스형식
OnPhotonSeializeView(PhotonStream stream, PhotonMessageInfo info)를 포함하고 있다.

int value1;
if(stream.IsWriting)
{
	stream.SendNext(value1);
}
else	
{
	value1 = (int)stream.ReciveNext();	
}

와 같은 형태로 되어있으며 값 형식만 사용이 가능하다. 참조형식(주소 값을 가진) 데이터 안됨
가능한 형식 : bool, byte, short, int, long, float, double, string, array(배열), Vector2, Vector3, Quaternion, Player(포톤)

** 참조 형식 데이터 동기화
아직 미숙

  1. PunRPC

동기화를 진행할 때 동일한 함수를 실행할 필요가 있다. 이때 사용하는것이 PunRPC로 사용방법은

public void Attack()
{
	photonView.RPC("AttackRPC", RpcTarget.어떤 형식을 사용할지 , PhotonNetwork.LocalPlayer.ActorNumber) 
}

[PunRPC]
public void AttackRPC(int playerNum)
{
	Debug.Log($"{playerNum}이 힘껏 때린다");
}

이런 형식을 구성하고 있다.
애니메이션 이벤트를 적용할 때도 AttackRPC 함수에 내용을 적용해주고 이벤트 실행 될 때 Attack()을 적용해주면 애니메이션 이벤트도 적용 가능하다.

RpcTarget. + 어떤형식 - 어떤형식이란 :

All : 모든 클라이언트에게 즉시 실행
Others : 다른 클라이언트에게 즉시 실행
MasterClient : 마스터 클라이언트에게 즉시 실행
AllViaServer : 모든 클라이언트에게 서버를 지나 실행
AllBuffered : 모든 클라이언트에게 즉시 실행
OtherBuffered : 다른 클리이언트에게 즉시 실행
AllBufferedViaServer : 모든 클라이언트에게 버서를 지나 실행

** 여기서 AllViaServer와 Buffer를 자세히 살펴보자
AllViaServer : 서버를 통해 모든 플레이어에게 동일한 함수를 동시에 주기위해 서버를 이용한다
Buffer : 버퍼에 저장을하고 함수가 일어난 후에 들어온 플레이어도 확인을 할 수 있게 저장해둔다.

지연보상

PunRPC에 대해 어쩔 수 없는 지연시간이 있다 이때 지연된 만틈 지연을 받은 플레이어가 일반 플레이어와 동일한 조건을 가질 수 있도록 보상을 해주는데 이것을 지연보상이라 말한다.(우리는 이를 렉이라고도 부른다)

[PunRPC]
private void Fire(int playerNum,int id, PhotonMessageInfo info)
{
    float lag = Mathf.Abs((float)PhotonNetwork.Time - (float)info.SentServerTime);

    GameObject obj = Instantiate(bullet, position, rotation);
    obj.GetComponent<Bullet>().Init(lag,id);
}

다음과 같이 구성을해서 Init에 대한 값을 lag으로 넘겨주고


public void Init(float lag, int id)
{
    rigid.velocity = transform.forward * bulletSpeed;
    rigid.position += rigid.velocity * lag;
    playerID = id;
}

bullet에서는 늦은 lag만큼 위치를 더해주고 시작하게된다.

0개의 댓글