Pun-01/Assets/Photon/PhotonUnityNetworking/Demos/DemoAsteroids/Scripts/Lobby/LobbyMainPanel.cs

372 lines
12 KiB
C#
Raw Permalink Normal View History

2022-07-08 09:14:55 +08:00
using ExitGames.Client.Photon;
using Photon.Realtime;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace Photon.Pun.Demo.Asteroids
{
public class LobbyMainPanel : MonoBehaviourPunCallbacks
{
[Header("Login Panel")]
public GameObject LoginPanel;
public InputField PlayerNameInput;
[Header("Selection Panel")]
public GameObject SelectionPanel;
[Header("Create Room Panel")]
public GameObject CreateRoomPanel;
public InputField RoomNameInputField;
public InputField MaxPlayersInputField;
[Header("Join Random Room Panel")]
public GameObject JoinRandomRoomPanel;
[Header("Room List Panel")]
public GameObject RoomListPanel;
public GameObject RoomListContent;
public GameObject RoomListEntryPrefab;
[Header("Inside Room Panel")]
public GameObject InsideRoomPanel;
public Button StartGameButton;
public GameObject PlayerListEntryPrefab;
private Dictionary<string, RoomInfo> cachedRoomList;
private Dictionary<string, GameObject> roomListEntries;
private Dictionary<int, GameObject> playerListEntries;
#region UNITY
public void Awake()
{
PhotonNetwork.AutomaticallySyncScene = true;
cachedRoomList = new Dictionary<string, RoomInfo>();
roomListEntries = new Dictionary<string, GameObject>();
PlayerNameInput.text = "Player " + Random.Range(1000, 10000);
}
#endregion
#region PUN CALLBACKS
public override void OnConnectedToMaster()
{
this.SetActivePanel(SelectionPanel.name);
}
public override void OnRoomListUpdate(List<RoomInfo> roomList)
{
ClearRoomListView();
UpdateCachedRoomList(roomList);
UpdateRoomListView();
}
public override void OnJoinedLobby()
{
// whenever this joins a new lobby, clear any previous room lists
cachedRoomList.Clear();
ClearRoomListView();
}
// note: when a client joins / creates a room, OnLeftLobby does not get called, even if the client was in a lobby before
public override void OnLeftLobby()
{
cachedRoomList.Clear();
ClearRoomListView();
}
public override void OnCreateRoomFailed(short returnCode, string message)
{
SetActivePanel(SelectionPanel.name);
}
public override void OnJoinRoomFailed(short returnCode, string message)
{
SetActivePanel(SelectionPanel.name);
}
public override void OnJoinRandomFailed(short returnCode, string message)
{
string roomName = "Room " + Random.Range(1000, 10000);
RoomOptions options = new RoomOptions {MaxPlayers = 8};
PhotonNetwork.CreateRoom(roomName, options, null);
}
public override void OnJoinedRoom()
{
// joining (or entering) a room invalidates any cached lobby room list (even if LeaveLobby was not called due to just joining a room)
cachedRoomList.Clear();
SetActivePanel(InsideRoomPanel.name);
if (playerListEntries == null)
{
playerListEntries = new Dictionary<int, GameObject>();
}
foreach (Player p in PhotonNetwork.PlayerList)
{
GameObject entry = Instantiate(PlayerListEntryPrefab);
entry.transform.SetParent(InsideRoomPanel.transform);
entry.transform.localScale = Vector3.one;
entry.GetComponent<PlayerListEntry>().Initialize(p.ActorNumber, p.NickName);
object isPlayerReady;
if (p.CustomProperties.TryGetValue(AsteroidsGame.PLAYER_READY, out isPlayerReady))
{
entry.GetComponent<PlayerListEntry>().SetPlayerReady((bool) isPlayerReady);
}
playerListEntries.Add(p.ActorNumber, entry);
}
StartGameButton.gameObject.SetActive(CheckPlayersReady());
Hashtable props = new Hashtable
{
{AsteroidsGame.PLAYER_LOADED_LEVEL, false}
};
PhotonNetwork.LocalPlayer.SetCustomProperties(props);
}
public override void OnLeftRoom()
{
SetActivePanel(SelectionPanel.name);
foreach (GameObject entry in playerListEntries.Values)
{
Destroy(entry.gameObject);
}
playerListEntries.Clear();
playerListEntries = null;
}
public override void OnPlayerEnteredRoom(Player newPlayer)
{
GameObject entry = Instantiate(PlayerListEntryPrefab);
entry.transform.SetParent(InsideRoomPanel.transform);
entry.transform.localScale = Vector3.one;
entry.GetComponent<PlayerListEntry>().Initialize(newPlayer.ActorNumber, newPlayer.NickName);
playerListEntries.Add(newPlayer.ActorNumber, entry);
StartGameButton.gameObject.SetActive(CheckPlayersReady());
}
public override void OnPlayerLeftRoom(Player otherPlayer)
{
Destroy(playerListEntries[otherPlayer.ActorNumber].gameObject);
playerListEntries.Remove(otherPlayer.ActorNumber);
StartGameButton.gameObject.SetActive(CheckPlayersReady());
}
public override void OnMasterClientSwitched(Player newMasterClient)
{
if (PhotonNetwork.LocalPlayer.ActorNumber == newMasterClient.ActorNumber)
{
StartGameButton.gameObject.SetActive(CheckPlayersReady());
}
}
public override void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
{
if (playerListEntries == null)
{
playerListEntries = new Dictionary<int, GameObject>();
}
GameObject entry;
if (playerListEntries.TryGetValue(targetPlayer.ActorNumber, out entry))
{
object isPlayerReady;
if (changedProps.TryGetValue(AsteroidsGame.PLAYER_READY, out isPlayerReady))
{
entry.GetComponent<PlayerListEntry>().SetPlayerReady((bool) isPlayerReady);
}
}
StartGameButton.gameObject.SetActive(CheckPlayersReady());
}
#endregion
#region UI CALLBACKS
public void OnBackButtonClicked()
{
if (PhotonNetwork.InLobby)
{
PhotonNetwork.LeaveLobby();
}
SetActivePanel(SelectionPanel.name);
}
public void OnCreateRoomButtonClicked()
{
string roomName = RoomNameInputField.text;
roomName = (roomName.Equals(string.Empty)) ? "Room " + Random.Range(1000, 10000) : roomName;
byte maxPlayers;
byte.TryParse(MaxPlayersInputField.text, out maxPlayers);
maxPlayers = (byte) Mathf.Clamp(maxPlayers, 2, 8);
RoomOptions options = new RoomOptions {MaxPlayers = maxPlayers, PlayerTtl = 10000 };
PhotonNetwork.CreateRoom(roomName, options, null);
}
public void OnJoinRandomRoomButtonClicked()
{
SetActivePanel(JoinRandomRoomPanel.name);
PhotonNetwork.JoinRandomRoom();
}
public void OnLeaveGameButtonClicked()
{
PhotonNetwork.LeaveRoom();
}
public void OnLoginButtonClicked()
{
string playerName = PlayerNameInput.text;
if (!playerName.Equals(""))
{
PhotonNetwork.LocalPlayer.NickName = playerName;
PhotonNetwork.ConnectUsingSettings();
}
else
{
Debug.LogError("Player Name is invalid.");
}
}
public void OnRoomListButtonClicked()
{
if (!PhotonNetwork.InLobby)
{
PhotonNetwork.JoinLobby();
}
SetActivePanel(RoomListPanel.name);
}
public void OnStartGameButtonClicked()
{
PhotonNetwork.CurrentRoom.IsOpen = false;
PhotonNetwork.CurrentRoom.IsVisible = false;
PhotonNetwork.LoadLevel("DemoAsteroids-GameScene");
}
#endregion
private bool CheckPlayersReady()
{
if (!PhotonNetwork.IsMasterClient)
{
return false;
}
foreach (Player p in PhotonNetwork.PlayerList)
{
object isPlayerReady;
if (p.CustomProperties.TryGetValue(AsteroidsGame.PLAYER_READY, out isPlayerReady))
{
if (!(bool) isPlayerReady)
{
return false;
}
}
else
{
return false;
}
}
return true;
}
private void ClearRoomListView()
{
foreach (GameObject entry in roomListEntries.Values)
{
Destroy(entry.gameObject);
}
roomListEntries.Clear();
}
public void LocalPlayerPropertiesUpdated()
{
StartGameButton.gameObject.SetActive(CheckPlayersReady());
}
private void SetActivePanel(string activePanel)
{
LoginPanel.SetActive(activePanel.Equals(LoginPanel.name));
SelectionPanel.SetActive(activePanel.Equals(SelectionPanel.name));
CreateRoomPanel.SetActive(activePanel.Equals(CreateRoomPanel.name));
JoinRandomRoomPanel.SetActive(activePanel.Equals(JoinRandomRoomPanel.name));
RoomListPanel.SetActive(activePanel.Equals(RoomListPanel.name)); // UI should call OnRoomListButtonClicked() to activate this
InsideRoomPanel.SetActive(activePanel.Equals(InsideRoomPanel.name));
}
private void UpdateCachedRoomList(List<RoomInfo> roomList)
{
foreach (RoomInfo info in roomList)
{
// Remove room from cached room list if it got closed, became invisible or was marked as removed
if (!info.IsOpen || !info.IsVisible || info.RemovedFromList)
{
if (cachedRoomList.ContainsKey(info.Name))
{
cachedRoomList.Remove(info.Name);
}
continue;
}
// Update cached room info
if (cachedRoomList.ContainsKey(info.Name))
{
cachedRoomList[info.Name] = info;
}
// Add new room info to cache
else
{
cachedRoomList.Add(info.Name, info);
}
}
}
private void UpdateRoomListView()
{
foreach (RoomInfo info in cachedRoomList.Values)
{
GameObject entry = Instantiate(RoomListEntryPrefab);
entry.transform.SetParent(RoomListContent.transform);
entry.transform.localScale = Vector3.one;
entry.GetComponent<RoomListEntry>().Initialize(info.Name, (byte)info.PlayerCount, info.MaxPlayers);
roomListEntries.Add(info.Name, entry);
}
}
}
}