※ 틀린 사항이 포함되어 있을수도 있습니다. 후기 남겨주시면 제대로 수정하고 학습하겠습니다
Network에서 로비나 룸을 만들 때 ui는 빠지지않고 들어간다. 이점을 생각해봤을 때 많은 ui요소를 인스펙터에 넣고 실수하지 않게 설정하는것은 어려울 수 있어서 ui바인딩을 이용해서 Network 연결, 로비, 룸을 구성할것이다(일부분은 직렬화 필요)

다음과같이 BaseUI를 통해 상속한 ui들을 Manager와 큰 틀인 Canvas에서 작은 단위인 ui들을 생성하고 로비와 룸을 구성해서 Network를 구성할것이다.
private GameObject roomPanelItem => GetUI("RoomPanelItemParent");
private GameObject createRoomPanel => GetUI("CreateRoomPanel");
private Button leaveLobbyButton => GetUI<Button>("LeaveLobbyButton");
private Button createRoomButton => GetUI<Button>("CreateRoomButton");
private void Start()
{
GetEvent("CreateLobbyButton").Click += data =>
{
createRoomPanel.SetActive(true);
roomPanelItem.SetActive(false);
createLobbyButton.interactable = false;
leaveLobbyButton.interactable = false;
};
}
빈 오브젝트나 해당 오브젝트를 컨트롤 할 수 있도록 GameObject, UI요소를 사용해야하는 Button은 GetUI<ㅁㅁㅁ> 와 같은 형식으로 작성해서 사용해준다.
GetEvent(string)에서 string형식의 사용할 인스펙터의 ui요소를 string으로 만들어서 해당 오브젝트의 이벤트를 사용해주면 이전에 기입해두었던 이벤트로 사용이 가능하다.
void Start()
{
currentRoomDic = new();
PhotonNetwork.ConnectUsingSettings();
}
#region ConnectNetwork & Lobby
public override void OnConnectedToMaster()
{
if (loadingPanel.activeSelf)
{
loadingPanel.SetActive(false);
}
PhotonNetwork.JoinLobby();
}
public override void OnDisconnected(DisconnectCause cause)
{
PhotonNetwork.ConnectUsingSettings();
}
public override void OnJoinedLobby()
{
lobbyPanel.SetActive(true);
StateCustomProperty(CurrentState.Lobby);
}
public override void OnCreatedRoom()
{
StateCustomProperty(CurrentState.InRoom);
}
public override void OnJoinedRoom()
{
lobbyPanel.SetActive(false);
roomPanel.SetActive(true);
roomManager.PlayerPanelSpawn();
}
시작 호출로 오브젝트를 켰다 꺼줬다를 실행하며 로비, 그리고 룸으로 이동할 수 있도록 구성하였다.
public override void OnRoomListUpdate(List<RoomInfo> roomList)
{
foreach (RoomInfo roomInfo in roomList)
{
//방이 사라질 때
if (roomInfo.RemovedFromList)
{
if (currentRoomDic.TryGetValue(roomInfo.Name, out GameObject obj))
{
Destroy(obj);
currentRoomDic.Remove(roomInfo.Name);
}
continue;
}
//방이 생길 때
if (currentRoomDic.ContainsKey(roomInfo.Name))
{
currentRoomDic[roomInfo.Name].GetComponent<JHT_RoomItem>().Init(roomInfo);
}
else
{
GameObject prefab = Instantiate(roomPanelPrefab);
prefab.transform.SetParent(roomListParent);
prefab.GetComponent<JHT_RoomItem>().Init(roomInfo);
currentRoomDic.Add(roomInfo.Name, prefab);
}
}
}
네트워크에서 제일 큰 학습중 하나였던 OnRoomListUpdate인데 이 함수를 호출하게되면 Roominfo의 List를 가져오게 되는데 룸의 정보를 담은 RoomInfo에서 방의 정보를 토대로 방 형식의 패널을 생성해주도록 하였다. (OnRoomListUpdate - 룸리스트가 변경될 때 호출됨)

플레이어의 친구목록에서 현재 내 친구의 게임 상태를 위해 생성한 커스텀 프러퍼티이다


방이 생성이 됐을 때 다음과 같이 커스텀프로퍼티를 설정해서 현재 플레이어의 상태를 해시테이블에서 플레이어의 Enum을 설정하도록 구성하였고 아직 완성하지는 못했다.
아직 구현되지 못한 상태이지만 브리핑을 하자면 현재 만들고있는 게임은 2:2형식으로 두개의 팀으로 나눌 필요가 있다.
먼저 커스텀프로퍼티로 Team을 만들고 "BlueTeam", "RedTeam"을 string 형식의 변수에 할당하는데 룸을 만드는 플레이어(마스터)가 Count를 가지고 있도록하고 해당 방을 구성했을 때 Dictionary<int,string>을 사용해서 플레이어가 어디팀의 위치에 있는지, 그리고 플레이어가 나갔을 때 해당 키를 가지고있는 플레이어의 count를 줄일 수 있게 설정할 필요가 있을거 같다.
public void SeparateTeam()
{
int blueCount = 0;
int redCount = 0;
foreach (Player player in PhotonNetwork.PlayerList)
{
string team = blueCount <= redCount ? "Blue" : "Red";
ExitGames.Client.Photon.Hashtable teamProperty = new();
teamProperty["Team"] = team;
PhotonNetwork.LocalPlayer.SetCustomProperties(teamProperty);
if (team == "Blue")
blueCount++;
else
redCount++;
}
}
플레이어가 룸에 들어왔을 때 PhotonNetwork.LocalPlayer.ActorNumber 자신의 고유 번호를 가지도록 이름을 설정 해놨다(추후에 Firebase.Auth.CurrentUser.DisplayNamed으로 수정예정) 하지만 다른 플레이어가 들어와도 자신의 ActorNumber로 표기되는 이슈가 있었다. 동기화에 대해 더 고민해보고 해결할 수 있도록 해야할거같다. (아직 해결 안됨)
