如何在Photon Pun 2中设置房间最小玩家数?
在Photon Pun 2中实现房间最小玩家数限制
要实现房间达到指定最小玩家数才能开始游戏的功能,你需要在现有代码基础上添加几个关键逻辑:
步骤1:添加最小玩家数配置
首先在Launcher类中添加最小玩家数的序列化字段,方便在Inspector面板中灵活调整:
[SerializeField] private byte maxPlayersPerRoom = 4; // 新增最小玩家数配置 [SerializeField] private byte minPlayersPerRoom = 2;
步骤2:更新按钮激活逻辑
修改控制startGameButton显示的逻辑,不仅要判断当前是否是房主(MasterClient),还要检查当前房间内的玩家数量是否达到最小要求:
修改OnJoinedRoom方法
把原来的startGameButton.SetActive(PhotonNetwork.IsMasterClient);替换成:
// 只有房主且玩家数达标时才显示开始按钮 startGameButton.SetActive(PhotonNetwork.IsMasterClient && PhotonNetwork.CurrentRoom.PlayerCount >= minPlayersPerRoom);
添加OnPlayerLeftRoom回调
原代码缺少玩家离开房间的回调,新增这个方法来更新按钮状态并清理离开玩家的列表项:
public override void OnPlayerLeftRoom(Player otherPlayer) { // 移除离开玩家的列表项 foreach (Transform child in playerListContent) { PlayerListItem item = child.GetComponent<PlayerListItem>(); if (item != null && item.Player == otherPlayer) { Destroy(child.gameObject); break; } } // 更新开始按钮状态 if (PhotonNetwork.IsMasterClient) { startGameButton.SetActive(PhotonNetwork.CurrentRoom.PlayerCount >= minPlayersPerRoom); } }
修改OnPlayerEnteredRoom方法
在玩家加入房间后,同步更新房主的开始按钮状态:
public override void OnPlayerEnteredRoom(Player newPlayer) { Instantiate(PlayerListItemPrefab, playerListContent).GetComponent<PlayerListItem>().SetUp(newPlayer); // 玩家加入后,更新房主的开始按钮状态 if (PhotonNetwork.IsMasterClient) { startGameButton.SetActive(PhotonNetwork.CurrentRoom.PlayerCount >= minPlayersPerRoom); } }
修改OnMasterClientSwitched方法
房主切换后,新的房主需要根据当前玩家数判断是否显示开始按钮:
public override void OnMasterClientSwitched(Player newMasterClient) { // 新房主判断是否满足最小玩家数要求 startGameButton.SetActive(PhotonNetwork.IsMasterClient && PhotonNetwork.CurrentRoom.PlayerCount >= minPlayersPerRoom); }
步骤3:添加开始游戏的校验
为了防止客户端绕过UI直接调用StartGame方法,在方法内部添加双重校验逻辑:
public void StartGame() { // 双重校验:确保是房主且玩家数达标 if (PhotonNetwork.IsMasterClient && PhotonNetwork.CurrentRoom.PlayerCount >= minPlayersPerRoom) { PhotonNetwork.LoadLevel(1); } else { // 可在此处添加UI提示,告知玩家"玩家数量不足,无法开始游戏" Debug.Log("玩家数量不足,无法开始游戏"); } }
完整修改后的Launcher代码
using System.Collections; using System.Collections.Generic; using UnityEngine; using Photon.Pun; using TMPro; using Photon.Realtime; using System.Linq; public class Launcher : MonoBehaviourPunCallbacks { public static Launcher Instance; [SerializeField] TMP_InputField roomNameInputField; [SerializeField] TMP_Text errorText; [SerializeField] TMP_Text roomNameText; [SerializeField] Transform roomListContent; [SerializeField] GameObject roomListItemPrefab; [SerializeField] GameObject PlayerListItemPrefab; [SerializeField] Transform playerListContent; [SerializeField] GameObject startGameButton; [SerializeField] private byte maxPlayersPerRoom = 4; [SerializeField] private byte minPlayersPerRoom = 2; // 新增最小玩家数配置 void Awake(){ Instance = this; } void Start() { Debug.Log("Connecting to Master"); PhotonNetwork.ConnectUsingSettings(); } public override void OnConnectedToMaster() { Debug.Log("Connected to Master"); PhotonNetwork.JoinLobby(); PhotonNetwork.AutomaticallySyncScene = true; } public override void OnJoinedLobby() { MenuSetting.Instance.OpenMenu("firstmenu"); Debug.Log("Joined Lobby"); } public void CreateRoom(){ if(string.IsNullOrEmpty(roomNameInputField.text)){ return; } PhotonNetwork.CreateRoom(roomNameInputField.text, new RoomOptions() {MaxPlayers = maxPlayersPerRoom}, null); MenuSetting.Instance.OpenMenu("Loading"); } public override void OnJoinedRoom() { MenuSetting.Instance.OpenMenu("room"); roomNameText.text = PhotonNetwork.CurrentRoom.Name; Player[] players = PhotonNetwork.PlayerList; foreach(Transform child in playerListContent) { Destroy(child.gameObject); } for(int i = 0; i < players.Count(); i++){ Instantiate(PlayerListItemPrefab, playerListContent).GetComponent<PlayerListItem>().SetUp(players[i]); } // 更新开始按钮状态:房主+玩家数达标 startGameButton.SetActive(PhotonNetwork.IsMasterClient && PhotonNetwork.CurrentRoom.PlayerCount >= minPlayersPerRoom); } public override void OnMasterClientSwitched(Player newMasterClient) { // 新房主判断是否满足最小玩家数要求 startGameButton.SetActive(PhotonNetwork.IsMasterClient && PhotonNetwork.CurrentRoom.PlayerCount >= minPlayersPerRoom); } public override void OnCreateRoomFailed(short returnCode, string message) { errorText.text = "Room Creation Failed: " + message; MenuSetting.Instance.OpenMenu("error"); } public void StartGame() { // 双重校验,防止作弊 if (PhotonNetwork.IsMasterClient && PhotonNetwork.CurrentRoom.PlayerCount >= minPlayersPerRoom) { PhotonNetwork.LoadLevel(1); } else { Debug.Log("玩家数量不足,无法开始游戏"); // 可在此处添加UI提示 } } public void LeaveRoom() { PhotonNetwork.LeaveRoom(); MenuSetting.Instance.OpenMenu("main_menu"); } public void JoinRoom(RoomInfo info){ PhotonNetwork.JoinRoom(info.Name); MenuSetting.Instance.OpenMenu("loading"); } public override void OnLeftRoom() { MenuSetting.Instance.OpenMenu("loading"); } public override void OnRoomListUpdate(List<RoomInfo> roomList) { foreach(Transform trans in roomListContent){ Destroy(trans.gameObject); } for(int i = 0; i < roomList.Count; i++){ if(roomList[i].RemovedFromList) continue; Instantiate(roomListItemPrefab, roomListContent).GetComponent<RoomListItem>().SetUp(roomList[i]); } } public override void OnPlayerEnteredRoom(Player newPlayer) { Instantiate(PlayerListItemPrefab, playerListContent).GetComponent<PlayerListItem>().SetUp(newPlayer); // 玩家加入后更新房主的开始按钮状态 if (PhotonNetwork.IsMasterClient) { startGameButton.SetActive(PhotonNetwork.CurrentRoom.PlayerCount >= minPlayersPerRoom); } } // 新增玩家离开房间的回调 public override void OnPlayerLeftRoom(Player otherPlayer) { // 移除离开玩家的列表项 foreach (Transform child in playerListContent) { PlayerListItem item = child.GetComponent<PlayerListItem>(); if (item != null && item.Player == otherPlayer) { Destroy(child.gameObject); break; } } // 更新房主的开始按钮状态 if (PhotonNetwork.IsMasterClient) { startGameButton.SetActive(PhotonNetwork.CurrentRoom.PlayerCount >= minPlayersPerRoom); } } }
内容的提问来源于stack exchange,提问作者Bimo Baskoro
相关产品推荐
相关产品推荐

