https://youtu.be/vURIykhil2c
이영호 교수님의 강의를 들으면서 정리한 노트입니다.
using Photon.Pun;를 먼저 하고
MonoBehaviourPun를 상속받으면 Network 객체가 됨
해당 오브젝트에는 PhotonView 컴포넌트가 붙어있어야 함
그리고 스크립트에서
if(photonView.IsMine)
조건문을 통해
현재 객체가 나의 객체인지 확인할 수 있음
Tip.
네트워크 게임은 빌드가 빈번하다.
따라서 프로젝트의 볼륨이 커질수록 빌드 시간이 오래 걸리므로
되도록 리소스 없는 상태에서 네트워크를 구현하고 이후 리소스를 붙이는 게 좋음
자동으로 위치 동기화를 시켜주는 게 있음
사용하기 편한데 몇 가지 문제가 있음
내부적으로 Photon Transform View는 예를 들어 60도를 회전한 경우 Lerp걸린 것처럼 움직이게 됨
몸체가 분리되서 가는 경우도 생김
따라서 위와 같은 경고 메시지도 뜨는데,
제대로 하려면 Photon View Clasic 을 쓰거나 IPunObservable을 쓰는 게 제일 좋다고 함
그럼 IPunObservable을 사용한 방식으로 구현해보자
IPunObservable 상속받은 후 Alt Enter하면 꼭 구현해야 할 함수가 자동으로 작성됨
// IPunObservable 상속 시 꼭 구현해야 하는 것
// - 데이터를 네트워크 사용자 간에 보내고 받고 하게 하는 콜백 함수
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
// stream - 데이터를 주고 받는 통로
// 내가 데이터를 보내는 중이라면
if(stream.IsWriting)
{
// 이 방안에 있는 모든 사용자에게 브로드캐스트
// - 내 포지션 값을 보내보자
stream.SendNext(transform.position);
stream.SendNext(transform.rotation);
stream.SendNext(camera.rotation);
}
// 내가 데이터를 받는 중이라면
else
{
// 순서대로 보내면 순서대로 들어옴. 근데 타입캐스팅 해주어야 함
transform.position = (Vector3)stream.ReceiveNext();
transform.rotation = (Quaternion)stream.ReceiveNext();
camera.rotation = (Quaternion)stream.ReceiveNext();
}
}
근데 위 코드처럼 하면 뚝뚝 끊겨 보일 수 있음
OnPhotonSerializeView에서 stream.ReceiveNext()를 통해 받은 값들을 바로 적용하지 않고
캐싱한 다음에 Update()에서 Lerp를 해주면 보간해줄 수 있다!
void Update()
{
if (false == photonView.IsMine)
{
transform.position = Vector3.Lerp(transform.position, remotePos, 10 * Time.deltaTime);
transform.rotation = Quaternion.Lerp(transform.rotation, remoteRot, 10 * Time.deltaTime);
camera.rotation = Quaternion.Lerp(camera.rotation, remoteCamRot, 10 * Time.deltaTime);
return;
}
}
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
// 내가 데이터를 보내는 중이라면
if(stream.IsWriting) // 내꺼 보내는 거
{
// 이 방안에 있는 모든 사용자에게 브로드캐스트
// - 내 포지션 값을 보내보자
stream.SendNext(transform.position);
stream.SendNext(transform.rotation);
stream.SendNext(camera.rotation);
}
// 내가 데이터를 받는 중이라면
else // 원격에 있는 나
{
// 순서대로 보내면 순서대로 들어옴. 근데 타입캐스팅 해주어야 함
remotePos = (Vector3)stream.ReceiveNext();
remoteRot = (Quaternion)stream.ReceiveNext();
remoteCamRot = (Quaternion)stream.ReceiveNext();
}
}
뭔가 아직은 이해가 잘 안된다..
OnPhotonSerializeView()에서 remotePos에 받은 다음
Update에서 IsMine이 아니라면 현재 객체에 저장을 해주는데
아 로컬 플레이어가 아니라면 입력을 통한 이동이 아닌
서버로부터 받은 pos를 적용시킨다고 보면 될 듯 하다..!
현재 씬에 해당 코드를 가진 플레이어가 여러 명일텐데
remotePos에는 원격에 있는 나의 position을 받아오는 건가보다