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) // 방목록 변경시 호출됨
커스텀 프로퍼티는 포톤에서 제공하는 방의 이름, 최대 참여인원, 현재 참여인원등의 정보외에 추가적으로 프로그래머가 원하는 동기화를 하기위해 직접 선언해줄 수 있는 방법이다.
ExitGames.Client.Photon.HashTable 자료구조를 사용해서 사용가능
모든 오브젝트를 동기화시 비용이 막대하기 때문에 원하는 부분만 동기화를 진행하면 된다. 동기화가 진행 되어야하는 객체에 PhotonView를 적용하고 사용한다. 이 때 viewID를 통해 오브젝트와 상호작용 가능함
-> MonobehaviourPun을 사용하면 편하다 (photonView를 사용할 수 있기때문) +
모든 플레이어의 화면에 생성하고 삭제가 될 필요가 있는 오브젝트를 앞에 PhotonNetwork를 붙이는데 Instantiate("Resources폴더 안의 프리팹이름",위치,회전);을 기입해서 사용하면 된다.
PhotonNetwork.Instantiate("PrefabName",position,rotation);
PhotonNetwork.Destroy(photonView);
데이터(변수)를 보내고 받는 형식의 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(포톤)
** 참조 형식 데이터 동기화
아직 미숙
동기화를 진행할 때 동일한 함수를 실행할 필요가 있다. 이때 사용하는것이 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만큼 위치를 더해주고 시작하게된다.