목차
- 소켓통신 구조
- PhotonNetwork.LoadLevel 로 씬전환 하게 하기
- PhotonView 넣어서 동기화 시키기
- PhotonView 의 IsMine 을 이용하여 내꺼만 움직이기
- IsMine == True 일 때 CamPos 활성화 하게 하기
- 쉽게 동기화 시켜줄 수 있는 Photon Transform View
- 닉네임 설정 해주기
- Photon OnPhotonSerializeView 동기화
- Lerp 로 끊기는 현상 보간
- Photon 총알 발사 PhotonNetwork.Instantiate
- Photon Ray 총알발사 PunRPC
- 정리
소켓통신 구조
GameServer 에 신호를 보내면
다른 컴퓨터도 그 신호를 다 받을 수 있게 함
PhotonNetwork.LoadLevel 로 씬전환 하게 하기
우리는 ConnectionScene 에서 GameScene 까지 갈 수 있게 해볼거임
지금까지는 방 생성하면 그냥 SceneManager 로 옮겼는데,
씬이 로드 되는 순간 들어오는 네트워크가 유실 되지 않기 위해서 사용
이제는
PhotonNetwork.LoadLevel(“씬 이름”);
를 이용할 거임
ConnectionManager Script -> PhotonNetwork.LoadLevel(“LobbyScene”);
LobbyManager Script -> PhotonNetwork.LoadLevel("GameScene");
ScnenManager로 씬 전환을 사용하고 있지만 (씬이 바뀌는 도중에 바뀌었다는 메시지를 다른 pc도 받아야하는데 전환되는 순간이면 해당 메시지를 잊어버릴 수 있는 상황이 생겨버린다. 그걸 막아주기 위한 함수가 LoadLevel 임!
빌드 세팅도 넣어주자
그러면 이제 씬 전환 가능!
PhotonView 넣어서 동기화 시키기
하지만 이렇게 됬다고 해서 여러친구들이 들어올 수 있는게 아님
이제 Player 에게 중요한 Component 를 넣어줄거임
우선 Player 를 Prefabs 폴더에 프리팹으로 넣어주자
그 후, Player 에게 PhotonView 라는 Component 를 넣을 거임
이게 붙어 있어야, 동기화 처리를 할 수 있고 자신인지 아닌지도 알 수 있다
View ID 가 유니크하게 할당을 해주기 때문임
그 후,
GameScene 을 관리 하는 GameManager 를 만들어 보자
코드로 들어가서
시작, 하면 Instantiate 를 해줄 거임
근데 우리가 아는 방법이 아니라, Photon 에서 주는 기능으로 생성 할 거임!
원래는 Factory 만들면서 Instantiate 해야하는데 이건 그럴 필요 없다.
한 가지 더 중요한건, 저 Player 는
꼭, Resources 폴더 안에 있어야 함!
이제 거의 다 됬다
하이어라키창에 플레이어가 존재하고 있으면 안되니까 Player 지우자!
멘토님이 플레이 해봤을 때, 다른 친구들도 멘토님꺼로 들어갔음 ㅋㅋ
그랬을 때
멘토님이 만드신건 Photon View 에 IsMine => True 로 되어있다
다른 사람들 꺼는 False
지금 컨트롤이 같이 된다. 점프도 그렇고, 카메라 돌리는것도 그렇고
내가 생성한게 아닌데, 같이 되는 현상이 발생함.
근데 지금 내가 움직여도 다른 컴에서는 움직이지도 않는다. 동기화가 아직 안된 상태임!
지금은 딱 생성만 동기화 시킨거임
PhotonView 의 IsMine 을 이용하여 내꺼만 움직이기
그래서 일단은, 내가 움직일 때 다른 친구들이 안움직이게 만들어 줄거임
PlayerMove.cs 로 가서
using Photon.Pun; 네임스페이스를 추가하고
MonoBehaviourPun 으로 상속받게 한다.
이걸 가지고 있으면, GetComponent 로 PhotonView 를 안가져와도 됨
그니까, 저걸 안하면
근데 저렇게 해서 좀 더 편하게 가져올 수 있다!
그래서 내것이 아니면 함수 실행 안되게 하는거임
PlayerRot 도 똑같이 MonoBehaviourPun 상속받고 위처럼 해줌
IsMine == True 일 때 CamPos 활성화 하게 하기
근데 여기서의 문제점이 있음.
GameScene 은 그대로..?
그 이유는 두 카메라가 둘 다 켜져있기 때문임!
그러니까, Resources 에 있는 Player 의 Campos 를 꺼놓고,
내것 일 때만 키게 하자
그리고 PlayerRot.cs 로 가서
쉽게 동기화 시켜줄 수 있는 Photon Transform View
사실 쉽게 동기화 시켜줄 수 있는 Photon 의 기능이 있음.
이거 임!
Photon Transform View !
이거 하면, Position 이랑 Rotation 을 똑같이 동기화 시켜준다
Photon View 가 이걸 관리해주기 때문에 Photon View 를 꼭 써야함
근데 우리는 이거 말고 코드로 구현 해볼거임!
닉네임 설정 해주기
에서 Legacy -> Text 생성 해서 NickName 으로 이름 바꾸자
Text 설정 이렇게 바꾸고
Canvas 는 World Space 로 바꿈
그리고
Canvas 사이즈는 다 Reset 하고,
NickName 의 Scale 을 엄청 작게 0.01 정도로 바꾸자
Text 색도 잘 보이게 설정 하자!
이 닉네임은 PlayerMove.cs 의 Start 에서 설정하자
NameSpace 에 UnityEngine.UI 추가
public Text nickName; 추가
Start() 에서,
photonView 를 만든 Owner 의 이름 NickName 으로 설정
nickName.text = photonView.Owner.NickName;
이걸 애초에 설정 해줬어야 함!
ConnectionManager.cs 로 가보자
로비 진입 전에 내 닉네임을 넣어야 함
Random.Range 를 넣어준건 Test 환경에서 들어 올 때마다 다른 이름이게 하려고 한거임
이 이름은 PhotonNectwork.Instantiate(asdf) 할 때 정보가 같이 넘어가는 것임
Photon OnPhotonSerializeView 동기화
이제 PhotonTransformView 가 아니라, 코드로 한번 구현 해보자
PlayerMove 에서 IPunObservable InterFace 를 추가하자!
인터페이스에는 함수의 정의가 들어가 있는데
인터페이스를 추가하면 함수를 무조건 추가 해라 라는거임
지금 그 함수를 안썼기 때문에 빨간줄 나는거고
저기서 Alt+Enter 해도 인터페이스 구현이 나옴!
아무것도 없더라도 함수가 존재해야 에러가 안남
그러면, Photon View Observed Components 에 나오게 됨!
Photon Transform View 에도 저 InterFace 가 있기 때문에 PhotonView 에서 관리함
Photon Transform View 안쓸거니까 지우자!
내 PC 에서는 보내고 다른 PC 에서는 받게 해주는게 이거임
IsWriting 은 IsMine 이 나 일때 (주겠다는 거임)
IsReading 은 IsMine 이 내가 아닐 때 (받겠다는 거임)
(Vector3) 와 (Quaternion) 으로 강제 형변환을 해주는것은, 저 클래스가 Object 클래스 이기 때문임
이제 이렇게 하면 PhotonTransformView 없이도 동기화 할 수 있음!
근데 이렇게 하면 엄청 끊긴다고 함
1초에 몇번 주겠다는 빈도에 따라서 , 받을 때도 1초에 몇 번 받게 됨 그걸 설정해야함
근데 이 텀이 좀 느려지면 툭툭툭 움직이는 느낌이 든다
이렇게 끊긴다면 선형 보간 (Lerp) 로 부드럽게 움직이게 하는 로직을 만들거임!
Lerp 로 끊기는 현상 보간
PlayerMove.cs 에서
도착위치, 회전값 변수 생성
그리고 이 함수에서 데이터를 받을 때, 저 변수로 받게 하자.
Lerp 를 쓰기 위함
그러면 다시 update 문으로 가서
내것이라면 원래 대로 움직이고, 내것이 아니라면, Lerp 를 이용해서 움직이게 할거임
여기서 저 조건문을 지우고,
이렇게 보간해서 움직이면 다른 플레이어들이 훨씬 부드럽게 움직이는것을 확인 할 수있음
그래도 좀 끊겨서, GameManager 에서 이렇게 추가!
Photon 총알 발사 PhotonNetwork.Instantiate
총알을 같이 발사함
그러니까, 내가 아니면 쏘지 않게 하는 위에서 해봤던걸 해보자
Photon.Pun 네임스페이스 추가,
MonoBehaviourPun 으로 상속 바꿔줌
PlayerFire 에서
IsMine 이 아니면 함수 끝내게 한다.
그러면 이제 내가 쏘면 나만 발사하게 할 수 있음!
근데 여기서 또 문제는, 왼쪽 알트키를 누르면 나는 나가는게 보이는데 상대방은 나가는게 보이지 않음!
일단 이걸 다 주석 처리하자
아까 했던것 처럼 이렇게 해보자
근데 안나갈거임. 왜??
Bullet 에 PhotonView 가 없고
Resources 에 넣지 않았기 때문!
이 두개는 무조건 필수임!!
저 두개를 해주자 PhotonView, Resources!!!
그러면 다른사람이 쏘는게 보임
(참고)
NickName 이 카메라 방향을 보게 만들어주기
이렇게 하면 NickName 이 Camera 앞방향으로 셋팅됨
Player 가 가지고 있는 Canvas 에 Assign 하면 됨!
Photon Ray 총알발사 PunRPC
Ray 의 이펙트는 아직 동기화 안했음!
이걸 RPC 로 해볼거임
Remote Procedure Calls
이걸 RPC 로 호출 해볼 거임
이렇게 바꿀 수 있다
RPC 로 쓸 함수 에는, [PunRPC] 를 꼭 붙여 줘야함!
붙여주는 이유는
여기 가보면 RPCs 가 있음 열어보자
방금 작성한 함수도 들어가 있다
이렇게 관리 해주는거기 때문에 PunRPC 를 꼭 붙여줘야 한다
단발성 이벤트에 RPC 를 많이 쓰고
계속 움직여야 하는 것에는 OnPhotonSerializeView 를 씀!
정리
정리 1.닉네임 PhotonNetwork.NickName = “이름”; 2. 씬전환 PhotonNetwork.LoadLevel(“씬이름”); 3. MonoBehaviourPun 상속 - photonView 변수에 자동으로 PhotonView가 담긴다. → MonoBehaviourPun 클래스에 PhotonView를 GetComponent 4. PhotonView (5 / 6 전제조건) - 데이터를 보내고/ 받고 - 플레이어간의 데이터를 연결 시켜주는 기능 - 내것 아닌지 판단 (isMine) 5. 플레이어 생성 - Player Prefab을 Resources 폴더에 꼭! - PhotonNetwork.Instantiate(“Player”, 생성위치, 생성 회전값); 6. Photon Transform View - 위치, 크기, 회전 값을 동기화 7. IpunObservable -> OnPhotonSerializeView(중요, 인터페이스이므로 반드시 구현) - stream.IsWriting == true 데이터를 보낸다. = IsMine → value(position, rotation) 값만 가능, 클래스는 못보낸다. - stream.IsReading == true 데이터를 받는다. → IsWriting 순서대로 받아야한다 → 오브젝트 형식으로 들어오므로 강제적 형변환 필수 8. OnPhotonSerializeView 호출빈도 - PhotonNetwork.SerializationRate = 60; - 100이 최대 - 연속적인 데이터(포지션, 로테이션값) 9. RPC 호출빈도(Remote Procedure call :원격프로시저호출) - PhotonNetwork.SendRate : 60; - 단발성(총알을 한번 발사해줘!), 1초에 몇번씩 RPC로 호출된 애를 보내겠다 - 이벤트 받아서 동기화 처리 (클릭 , 버튼, 충돌 등) - 이 부분 현숙이한테 정리 도움 받음 |
'Photon' 카테고리의 다른 글
Photon 여섯 째날 (LobbyScene 꾸미기, RemoveRoomListUI(),UpdateRoomCache()) (1) | 2022.09.14 |
---|---|
Photon 다섯 째날 (RPC로 OnDamage, RPC.애니메이션(상태머신), RPC.총,Connection Scene UI 꾸미기) (1) | 2022.09.13 |
Photon 셋째 날(PlayerFire , PlayerMove.OnDamage()) (0) | 2022.09.07 |
Photon 둘째 날 (PlayerMove, PlayerRot) (0) | 2022.09.06 |
Photon 첫 날(photon의 구조, 세팅, 서버연결, 방 생성, 입장) (0) | 2022.09.06 |