내일배움캠프 47일차 TIL, 포톤

황오영·2024년 6월 24일
0

TIL

목록 보기
47/56
post-thumbnail
  • 오늘은 팀 프로젝트인 포트리스류 게임 만들기 위해 서버작업이 필요해서 포톤관련해서 내용을 정리해보고자 한다. 지난번에 한번 정리하긴 했었는데 실제로 작업해보면서 잘 모르겠는 개념을 정리하려고 한다.
    <출처 : https://velog.io/@hhj3258/123>

포톤과 동기화

  • 다른작업보다 제일 어려운것이 오브젝트 관련해서 동기화 하는 작업이 어려웠다.
  • 특히 게임내 서로 통신하는 과정에 대한 로직이 그냥 유니티 1인게임과는 방식이 달라서 힘들었다.

동기화를 위한 컴포넌트

  • PhotonView : 이 스크립트 컴포넌트가 있어야지 네트워크 동기화가 가능하다. Rigidbody, transform, animator가 있어 동기화가 필요한 컴포넌트에 관련된 스크립트를 붙여주면 된다.
  • 생성 코드, 생성 역시 마찬가지 유니티 내부 Instantiate에 생성하는 것이 아닌 '동기화'가 필요한 객체이기 때문에 유니티 내부에서 함수를 이용하는것이 아니라 포톤 함수를 이용해야한다.
    private void SpawnPlayer()
    {
        int idx = PhotonNetwork.LocalPlayer.ActorNumber;
        GameObject prefab = Managers.Resource.Load<GameObject>("Prefabs/Player");
        GameObject go;
        if (idx == 1)
        {
            go = PhotonNetwork.Instantiate(Path.Combine("Prefabs", "Player"), new Vector3(-3, 2, 0), Quaternion.identity);
        }
        else
        {
            go = PhotonNetwork.Instantiate(Path.Combine("Prefabs", "Player"), new Vector3(3, 2, 0), Quaternion.identity);
        }
    }	
  • 이런식으로 Resources 폴더에있는것을 찾아와야 한다.
  • 실제로 photonView.IsMine을 통해 자기 객체인지 확인할 수 있고 실제 움직이는 것을 오리지널이고 복제본은 오리지널의 위치와 회전 등 동기화를 받을 뿐
  • 파괴 역시PhotonNetwork.Destroy()을 사용해야한다.

RPC(Remote Procedure call)

  • 원격 프로시저 호출, 별도의 원격 제어를 위한 코딩 없이 다른 주소 공간에서 프로시저를 실행 할 수 있게 하는 프로세스 간 통신 기술 원격프로시저르 이용해 프로그래머는 함수가 실행 프로그램에 로컬 위치에 있든 원격위치에 잇든 동일한 코드를 사용할 수 있다.
  • 이 코드를 사용하는 이유는 PhotonView의 경우 모든 오브젝트들을 동기화 할 수 없기때문 이 동기화 과정은 많은 리소스가 들어간다. 그러므로 RPC가 필요하다.
  • 호출하기 위해선 photonView.RPC()를 통해 호출하고
 [PunRPC]
    public void [함수이름]()
    {
    }

메서드 위에 RPC를 붙여줘야한다. 대표적으로 총알을 발사하는 로직, 이럴경우 위치 동기화가 되지 않아도 부드러운 총알의 움직임이 구현 가능

커스텀 프로퍼티

  • 키 - 값 형태의 해시테이블로 구성, 변수를 동기화 시켜준다.
  • 예를 들면 로비에서 플레이어들의 레디 상태를 체크하기 위해 커스텀 프로퍼티를 사용할 수 있다.
    public override void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
    {
        GameObject entry;
        if (_playerRowDict.TryGetValue(targetPlayer.ActorNumber, out entry))
        {
            object isPlayerReady;
            if (changedProps.TryGetValue("isReady", out isPlayerReady))
            {
                entry.GetComponent<LobbyPlayerRow>().SetReadyUI((bool)isPlayerReady);
            }
        }

        bool isAllReady = CheckAllPlayerReady();
        OnSetGameStartButton.Invoke(isAllReady);
    }
profile
게임개발을 꿈꾸는 개발자

0개의 댓글