Unity/Photon Pun2

[Tip] 유저 강퇴의 처리

몽실KUN 2020. 4. 26. 07:04

유저 강퇴의 처리 방법에는 여러가지가 있겠지만은... 여기서는 Photon Pun2의 제공하는 방법을 쓰지 않고 약간의 꼼수를 구현해서 만들기로 했다.

 

MasterClient즉, 방장이 다른 플레이어를 내쫓는 Photon Pun2의 방법은 "closeConnect" 인데, 즉 다시 말해 상대 플레이러를 "강제 종료" 시키는 것이다.  물론 접속이 차단되면, 이를 캐치해서 재접속을 실행하게 만드는 방법도 있으나... 여기서는 플레이어의 customProperty를 이용해서 제어를 하기로 했다.

 

...
    public void kickPlayerButton()
    {
        ExitGames.Client.Photon.Hashtable hashtable
            = new ExitGames.Client.Photon.Hashtable();
        hashtable.Add("isKicked", true);
        player.SetCustomProperties(hashtable);
    }
...

 

간단한 코드다. Kick Player 버튼을 누르면 해당 플레이어의 상태값에 isKicked = true를 추가하는 것이다.

 

...
    public void refreshPlayerNameList()
    {
        destroyAllPlayerNameRecord();
        Dictionary<int, Player> lists = PhotonNetwork.CurrentRoom.Players;

        if (lists == null || lists.Count == 0)
        {
            return;
        }

        foreach(int key in lists.Keys)
        {
            Player player = lists[key];
            GameObject obj = Instantiate(playerNameRecord);
            PlayerNameRecord pnr = obj.GetComponent<PlayerNameRecord>();
            pnr.setPlayer(player);
            obj.transform.SetParent(scrollRect.content.transform, false);
        }
    }
...

플레이어 목록을 갱신하는 함수이다.

사실, 모든 플레이어를 지우고 전부 새로 그리는 것이 아니라, 전체 비교를 해서 추가되거나 빠진 플레이어만 업데이트 하는 방법도 생각했었으나... 일단은 이것으로도 문제가 없는 것 같아 올린다.

 

...
    public void initialize()
    {
        if (PhotonNetwork.LocalPlayer.IsMasterClient && !player.IsLocal)
        {
            kickButton.gameObject.SetActive(true);
        }
        else
        {
            kickButton.gameObject.SetActive(false);
        }
    }
...

로컬유저가 마스터클라이언트(방장)이고, 현재 레코드의 플레이어가 로컬유저가 아닌 경우에만 강퇴 버튼이 보이게 한다. 즉, 다시 말해서 방장은 다른 플레이어를 강퇴할 수 있다.

 

...
    public override void OnPlayerPropertiesUpdate(Player targetPlayer
                     , ExitGames.Client.Photon.Hashtable changedProps)
    {
        if (targetPlayer == PhotonNetwork.LocalPlayer)
        {
            // isKicked property가 존재할경우
            if (changedProps["isKicked"] != null)
            {
                // 이게 true인 경우에만 진행
                if ((bool)changedProps["isKicked"])
                {
                    string[] _removeProperties = new string[1];
                    _removeProperties[0] = "isKicked";
                    PhotonNetwork.RemovePlayerCustomProperties(_removeProperties);
                    PhotonNetwork.LeaveRoom();
                }
            }
        }
    }
 ...

플레이어의 프로퍼티가 변경되면, OnPlayerPropertiesUpdate 함수가 호출된다. targetPlayer가 LocalPlayer가 아니면 함수를 강제 종료하게 해두어도 그만이다.