Unity Network with Photon

장현태입니다·2025년 7월 31일

※ 틀린 사항이 포함되어 있을수도 있습니다. 후기 남겨주시면 수정하고 학습하겠습니다

  1. Photon에서 이전에 SetCustomProperty가 비동기적으로 동작한다고 생각했는데 그냥 데이터 업데이트가 느리게? 동기화 되는거같다.

  2. 실수를 많이해서 버그로 인해 인게임까지 원활하게 이뤄지지 못한거같다 더 주의해서 코드를 작성해야겠다.

  3. Manager 종류의 순서를 정리해서 작성해야겠다 꼬이게되면 Manager의 특성은 사라지고 버그만 나오는거 같아서 더 분석하고 코드를 작성해야겠다

RoomManager에서 게임시작 버튼 클릭시 활성화되는 버튼인데 처음에 게임 시작을 할 때 마스터 클라이언트만
게임 시작버튼을 누르기 때문에 씬은 동기화가 되지만 다른 플레이어들에게 씬이 변환될 때 다른 동작은 
동기화되지 않는다 이를 해결하기위해 커스텀프로퍼티를 하나 더 추가해서 모든 플레이어가 게임시작 버튼을
마스터 클라이언트가 눌렀을 때 변환될 수 있도록 조절하였다.

public void GameStart()
{
    if (PhotonNetwork.IsMasterClient && AllPlayerReadyCheck()
        && (int)PhotonNetwork.CurrentRoom.CustomProperties["RedCount"] >= 1
        && (int)PhotonNetwork.CurrentRoom.CustomProperties["BlueCount"] >= 1)
    {
        JHT_NetworkManager.NetworkInstance.StateCustomProperty(CurrentState.InGame);
        JHT_NetworkManager.NetworkInstance.SetGameCustomProperty(true);

        //해당 게임씬 넣기
        StartCoroutine(WaitForLoad(PhotonNetwork.LocalPlayer));

    }
}

IEnumerator WaitForLoad(Player player)
{
    while (!player.CustomProperties.ContainsKey("Team") || !player.CustomProperties.ContainsKey("Character"))
        yield return null;

    int playerIndex = (int)player.CustomProperties["Character"];
    Vector3 spawnPos = (TeamSetting)player.CustomProperties["Team"] == TeamSetting.Red ? new Vector3(35, 0, 0) : new Vector3(-35, 0, 0);
    Quaternion rot = (TeamSetting)player.CustomProperties["Team"] == TeamSetting.Red ? Quaternion.Euler(0, 270, 0) : Quaternion.Euler(0, 90, 0);

    GameObject obj = PhotonNetwork.Instantiate(JHT_NetworkManager.NetworkInstance.characters[playerIndex].name, spawnPos, rot);
}

NetworkManager

OnPlayerPropertiesUpdate를 통해 해당 플레이어의 커스텀 프로퍼티가 변할 때 이벤트를 호출해준다
변환된 bool값에 따라 coroutine에서 변환된 GamePlay의 value값을 가져와서 if문으로 실행해주었다

public void SetGameCustomProperty(bool _value)
{
    ExitGames.Client.Photon.Hashtable gameStart = new();
    bool isStart = _value;
    gameStart["GamePlay"] = isStart;
    PhotonNetwork.LocalPlayer.SetCustomProperties(gameStart);


    if (PhotonNetwork.LocalPlayer.CustomProperties.TryGetValue("GamePlay", out object value))
    {
        OnGameStart?.Invoke((bool)value);
    }
}


public override void OnPlayerPropertiesUpdate(Player targetPlayer, ExitGames.Client.Photon.Hashtable changedProps)
{
    if (changedProps.ContainsKey("GamePlay"))
    {
        StartCoroutine(GameStartCor(targetPlayer, changedProps));
    }

}


IEnumerator GameStartCor(Player targetPlayer, ExitGames.Client.Photon.Hashtable changedProps)
{
    yield return null;
    if (changedProps.TryGetValue("GamePlay", out object value))
    {
        if ((bool)value)
        {
            roomManager.canvasPanel.SetActive(!(bool)value);
            PhotonNetwork.LoadLevel("GameScenes");
        }
        else
        {
            roomManager.canvasPanel.SetActive(!(bool)value);
            StateCustomProperty(CurrentState.Lobby);
        }
    }
}

구현 결과

0개의 댓글