-
PUN2 - 네트워크 공부(강의 정리)TIL 2023. 10. 24. 20:10반응형
포톤 PUN2
#Window -> Photon Unity Networking -> PUN Wizard
에서 필요한 부분 수정가능
ㅡ
#TopPanel ==>
현재 접속상태 Text로 확인 시켜주기
PhotonNetwork.NetworkClientState;
ㅡ
#MainPanel==>
각각의 패널에 사용해야 할 게임오브젝트&UI에 연결(변수로 호출)
MonoBehaviourPunCallbacks라는
네트워크에 뭔가를 요청하고, 그에대한 콜백들이 들어올 때 사용하는것을 상속받음
각각의 콜백들(On~~메서드들은)
오버라이드로 준비되어 있으며
호출에 따라 실행or파라미터값을 통해 실행된다.
OnJoinRandomFailed()=>
MaxPlayer 설정가능
OnJoinedRoom()=>
방에 접속했을 때,
그 안에 플레이어들에대한 정보를 보여준다.
Hashtable은 포톤(Photon)에서 만들어놓은 해시테이블이므로
네임스페이스에서 using을 해주어야 한다.
미리 지정된 각각의 키 값과 밸류값을 사용중
CheckPlayersReady()=>
스타트 버튼(시작 결정 버튼)을 활성화 할지 말지에 대해 결정함
OnStartGameButtonClicked()=>
로비->방에서 모두가 동의 후 시작하였을 때,
넘어갈 게임 씬을 연결한다. PhotonNetwork.LoadLevel("넘어갈 방");
기본적으로 로비에서 필요한 콜백들을 기본적으로 미리 생성되어 놓았으므로,
간단한 경우에는 여기서 일부만 수정하여서 사용하여도 된다.
아닌 경우엔 따로 구축하는게 더 나을듯?
#수정 :
CheckPlayersReady()에서
마스터 서버에 접속한 이후(PhotonNetwork.IsMasterClient에 변수가 담겨있음)
if(PotonNetwork.LocalPlayer.ActorNumber < 2)
return false;
로 추가적인 플레이어 인원 제한을 건다.
#주의!:
씬 로드 시 유니티 기능인 LoadSecne를 사용하게 된다면 자신만 넘어감
반드시 포톤을 사용한 멀티 플레이 구현시에는 PhotonNetwork.LoadLevel("넘어갈 씬");
을 사용하여 주어야 한다.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
#플레이어와 상호작용하는 오브젝트 처리()
해당 오브젝트에 Photon View 컴포넌트를 추가한다.
해당 컴포넌트에 포함된 View ID 가 동일한 인원들과 동기화 시키는것이다.
+누가 오너인지 체크해서 그 오너의 값들을 동기화 시킨다.
#플레이어가 조종하는 오브젝트 처리
마찬가지로 해당 오브젝트에 Photon View 컴포넌트를 추가한다.
또한 추가적으로 Photon Transform View 컴포넌트도 추가한다.
이건 무슨 역할? View ID가 동일한 오브젝트들의 위치를 동기화 시킨다.
스크립트 단계에서 부터 설계가 필요하다.
각각 필요한 오브젝트들은 프리팹으로 제작하여 놓고,
정확한 경로를 알아둬야 한다.
#플레이어 스크립트(기본적으로 제공하는 값으로 자동 동기화 하기)
MonoBehaviourPun를 우선 상속받게 한다.
이는 MonoBehaviour와 동일하지만, 추가적으로 Pun의 기능을 사용할 수 있게 해준다
Update()에서
if(PhotonView.IsMine) //이 오브젝트가 내 것인가?(내가 만든건가or호스트 건가)
내꺼라면 진행할 조작~이동... 등등
ㅡ
#플레이어와 상호작용하는 오브젝트(기본적으로 제공하는 방식 외 원하는 방식으로 동기화 하고 싶은 경우)
MonoBehaviourPun에 더해서 , 추가적으로 IPunObservable을 상속받는다.
그리고 IPunObservable에 걸려있는
OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
메서드를 생성할 수 있게 되는데,
여기서 사용자 정의 동기화 코드를 나타낼 수 있게 된다.
if(strem.IsWriting) // 호스트인 경우 : 내가 게임에 필요한 정보를 쓰는중
{
stream.SendNext(rigidbody.position);
stream.SendNext(rigidbody.velocity);
}
else // 손님인 경우 : 호스트가 적은 정보를 받아온다. 위에서 호스트가 쓴 순서를 그대로 받아줘야 한다.
{
rigidbody.position = (Vector2)stream.ReceiveNext();
rigidbody.velocity = (Vector2)stream.ReceiveNext();
}
이 외에도 이 부분에도 여러 변수를 호스트가 쓴 값과 동기화가 가능하다.
Start() 에서
if(!photonView.AmOwner)
return;
를 진행한다. 이유? ==>
호스트가 아닌 이상 아래에 진행할 Launch()와 같은 작업,
즉 오브젝트가 이동하고, 작동하는 부분이 필요가 없다.
[손님은 호스트가 작성하는 정보를 받아서 업데이트 할 뿐이므로]
추가적으로 오브젝트가 실제 작동하는 메서드(Launch())에도,
해당 검사를 추가적으로 진행하여 주어도 좋다.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
#게임 매니저
마찬가지로 Photon View 컴포넌트를 추가,
MonoBehaviourPunCallbacks을 상속 받음
Temp()
{
int idx = PhotonNetwork.LocalPlayer.ActorNumber; // 내 번호(View ID)가 무엇인지 확인
GameObject prefab = Resources.Load<GameObject>("Paddle") // 원하는 프리팹이 저장된 경로 + .Load<GameObject>("원하는 프리팹 이름") 을 통하여 불러온다
if(idx == 1)
{
PhotonNetwork.Instantiate(prefab.name, new Vector3(-12, 0, 0), Quaternion.identity) //마찬가지로 일반 생성하면, 본인 화면에서만 보이게 됨
}
PhotonNetwork.Instantiate(prefab.name, new Vector3(12, 0, 0), Quaternion.identity)
}
추가적으로
ball = prefab.GetComponent<TempCS>(); 와 같이 컴포넌트 획득도 가능
위의 메서드들을 Start에서 실행하면, 들어오는 모든 유저들이 생성하게 된다.
하지만 볼 처럼 플레이어 수에따라 생성되면 곤란한 경우의 오브젝트는
if(photonView.AmOwner)
SpawnBall();
이처럼 오너만 실행(생성)하도록 제한한다.
+
점수 획득과 같은 부분에서는
마찬가지로 오너인 경우에만 처리를 진행한다.
if(photonView.AmOwner)
하지만 이러면 오너만 보이기 때문에, 게스트에게도 보여줘야한다.
우선 정보를 처리하는 오너 파트에서 해당 부분의 정보를 타겟들에게 뿌려준다.
photonView.RPC("UpdateScore", RpcTarget.All, player1Score,player2Score);
많은 변화를 손님이 읽어야 하는경우는 View를 사용하지만,
자주 읽어오지 않는 정보의 경우엔 위와 아래처럼 RPC를 사용해야 한다.
[PunRPC]
public void UpdateScore(int score1, int score2)
{
player1Text.text score1.ToString();
playey2Text.text score2.ToString()
}
ㅡㅡ
OnLeftRoom() //방을 떠날 때
{
SceneManager.LoadScene("나갈 씬이름");
}
왜 아까는 PhotonNetwork.LoadLevel("넘어갈 방"); 사용해놓고 여기선
씬 매니저를 통해 나가는가?
위의 경우에선 호스트와 게스트 다 같이 이동하는 경우지만,
이 경우엔 각각 나가게 되므로, 씬 매니저를 이용한다.
게임이 끝나고 한번에 나가져야 하는 경우?
if(게임이 끝나는 조건)
PhotonNetwork.LeaveRoom(); 을 사용하여 다 같이 나가도록 한다.
이 경우 로비 씬으로 넘어가게 되는데,
이미 로그인이 된 상태라서 로그인 버튼이 작동하지 않게 된다.
MainPanel.cs에서 처리하여 주어야 한다.
Start()
if(PhotonNetwork.NetworkClientState == ClientState.Joined) //마스터 서버에 이미 접속한 상태
this.SetActivePanel(SelectionPanel.name);
+생성된 프리팹의 정보를 비교할 땐, Contains를 사용한다.
예시) coll.name.Contains("오브젝트")
+게스트라도 Rigidbody 등의 컴포넌트 정보는 가지고 가야한다.
작동 안하게 됨반응형'TIL' 카테고리의 다른 글
네트워크 게임을 개발하는데 필요한 이론적 배경-2 (0) 2023.10.24 네트워크 게임 개발 이론-1 (1) 2023.10.24 최종 프로젝트 - 1 일차 / 플레이어 조작 로직 결정 (0) 2023.10.23 델리게이트와 람다[예시-팝업] (0) 2023.10.18 C# 10/17 - 스택(Stack)과 제네릭(Generic) (2) 2023.10.17