You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 11:15:38