주녘공부일지

[더 챌린저스] 동기화(RPC) & 네트워크(Photon) 본문

GameDevelopment/[Unity] Project

[더 챌린저스] 동기화(RPC) & 네트워크(Photon)

주녘 2024. 9. 9. 14:30

1. 동기화 처리

서버 프로그래머 파트에서 제공한 RPC 함수를 필요에 따라 클라이언트에서 제어하며 사용함

 

1) 포톤에게 동기화 생성 요청

모노비헤이비어포톤 클래스를 베이스 클래스로 상속받는 클래스를 가진 프리팹을 대상으로 해야 함

- 생성된 오브젝트는 활성화되는 시점에 고유한 ID를 받고, 활성화시킨 클라이언트가 자신인지 확인할 수 있음

- 동일한 프리팹을 방 안의 모든 클라이언트에 생성하고 완료 시점을 확인할 수 있음 ( 동기화 완료 )

 > 같은 오브젝트가 모든 클라이언트에 존재함을 보장받음

 

2) 브로드캐스트 함수를 호출

- 포톤을 통해 브로드캐스트 함수를 호출해 모든 클라이언트에 동일한 함수가 호출되게 함으로써 동기화

 

3) 변수 동기화

FixedUpdate 주기를 기준으로 변수를 동기화하는 기능을 하기 위해 변수를 등록, 해제하는 함수

+ 필요에 따라 Rigidbody2D, Transform, Animation Parameter 등을 동기화 할 수 있음

    protected override void OnMineSerializeView(PhotonWriteStream stream)
    {
        stream.Write(currHP);
        stream.Write(currState);
        stream.Write(teamType);
        stream.Write(jumpState);
        stream.Write(invincibility);
        stream.Write(superArmour);

        base.OnMineSerializeView(stream);
    }

    protected override void OnOtherSerializeView(PhotonReadStream stream)
    {
        currHP = stream.Read<float>();
        currState = stream.Read<ENUM_PLAYER_STATE>();
        teamType = stream.Read<ENUM_TEAM_TYPE>();
        jumpState = stream.Read<bool>();
        invincibility = stream.Read<bool>();
        superArmour = stream.Read<bool>();

        base.OnOtherSerializeView(stream);
    }

2. 네트워크 순차 연동 실행

두 명의 유저가 동시에 게임을 시작하기 위해 필요한 조건을 실행 순서를 지정하여 정보를 공유하고 해당 정보에 따라 완료된 시점을 받아 실행 순서에 따른 로직을 실행하기 위한 순차 실행기

- 방에 B(유저)가 입장하면 A(방장)에서 실행됨

- 플레이어 프로퍼티, 등을 이용해 A, B의 상태를 확인

 

+ 게임에 돌입할 때 생성되는 클래스(UserSyncMediator)

 ->모든 클라이언트에게 동일한 로직의 함수를 호출하는 브로드캐스트 함수를 사용하기 위한 포톤객체

    protected IEnumerator INetworkSequenceExecuter()
    {
        // 0. 데이터 싱크
        PhotonLogicHandler.Instance.RequestSyncDataAll();

        // 1. 연결 확인
        yield return new WaitUntil(() => Get_PhotonCheck(ENUM_PLAYER_STATE_PROPERTIES.DATA_SYNC));

        // 2. 레디 확인 (방장의 레디 -> 시작 / 방장의 레디조건 : 입장한 유저의 준비완료)
        yield return new WaitUntil(() => Get_PhotonCheck(ENUM_PLAYER_STATE_PROPERTIES.READY));
        PhotonLogicHandler.Instance.RequestGameStart(); // 방 정보 - 게임 시작 상태로 변경

        // 게임 돌입할 때 UserSyncMediator 생성
        Managers.Resource.InstantiateEveryone("UserSyncMediator");

        // 3. 동기화객체 생성 체크
        yield return new WaitUntil(IsConnect_UserSyncMediator);
        userSyncMediator.Sync_ShowGameInfo(); // 캐릭터 선택 창 돌입

        // 4. 캐릭터 선택 확인
        yield return new WaitUntil(() => Get_PhotonCheck(ENUM_PLAYER_STATE_PROPERTIES.CHARACTER));
        userSyncMediator.Sync_ShowGameStartInfo(); // 양 쪽의 정보를 보여주고 배틀씬 이동

        // 5. 씬 로드 확인
        yield return new WaitUntil(() => Get_PhotonCheck(ENUM_PLAYER_STATE_PROPERTIES.SCENE_SYNC));
        // 캐릭터 소환은 이 시점에 BattleScene의 Start문에서 처리됨

        // 6. 캐릭터 로드 확인
        yield return new WaitUntil(() => Get_PhotonCheck(ENUM_PLAYER_STATE_PROPERTIES.CHARACTER_SYNC));
        userSyncMediator.Sync_GameStartEffect(); // 게임 실행

        // 7. 커스텀 플레이어 프로퍼티 데이터 값 초기화
        userSyncMediator.Sync_RequestUnSyncDataAll();
    }

3. 네트워크 공유 데이터

- 현재 속해있는 방의 정보와 방에 있는 유저(플레이어)의 정보를 얻기 위해 콜백함수를 등록, 해제하는 함수

 ( 인터페이스 클래스로 다중 상속받아 정보가 필요하다면 어디서든 사용할 수 있음 ) 

    protected override void OnEnable()
    {
        base.OnEnable();

        this.RegisterRoomCallback();

        PhotonLogicHandler.Instance.onEnterRoomPlayer -= OnEnterRoomCallBack;
        PhotonLogicHandler.Instance.onLeftRoomPlayer -= OnExitRoomCallBack;

        PhotonLogicHandler.Instance.onEnterRoomPlayer += OnEnterRoomCallBack;
        PhotonLogicHandler.Instance.onLeftRoomPlayer += OnExitRoomCallBack;

    }

    protected override void OnDisable()
    {
        base.OnDisable();

        PhotonLogicHandler.Instance.onEnterRoomPlayer -= OnEnterRoomCallBack;
        PhotonLogicHandler.Instance.onLeftRoomPlayer -= OnExitRoomCallBack;

        this.UnregisterRoomCallback();
    }
    
    // 방의 정보가 갱신되면 호출 - 방장에게만 변경 가능한 권한이 있음
    public void OnUpdateRoomProperty(CustomRoomProperty property) { ... }

    // 방에 있는 플레이어의 정보가 갱신되면 호출
    public void OnUpdateRoomPlayerProperty(CustomPlayerProperty property) { ... }

4. Attack, Effect Object

- 동기화되는 오브젝트들의 공통적인 기능들을 추상화하기 위해 상속 구조도를 설계해 구현함

동기화 되는 오브젝트들의 상속 구조도

Knight 캐릭터 영상
Wizard 캐릭터 영상