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

Photon Pun Unity 邀玩家问题:房主创房后Lobby玩家列表不显示

解决Photon多人游戏大厅玩家列表不显示问题

核心问题分析

你的代码存在几个关键问题导致大厅玩家列表无法显示:

  • PhotonNetwork.PlayerList的范围错误:这个API仅返回当前所在房间内的玩家,房主创建房间后已经离开大厅,自然拿不到大厅里的其他玩家。
  • 自定义属性依赖未落实:如果其他玩家没有主动设置status为lobby的自定义属性,你的判断条件会直接过滤掉所有玩家。
  • 列表刷新时机单一:仅在点击按钮时刷新列表,无法响应玩家进出大厅的实时变化。

修复方案及代码调整

1. 替换玩家列表获取方式

改用PhotonNetwork.PlayerListOthersInLobby获取大厅内的其他玩家,同时可补充自身在大厅时的显示(如果需要)。

2. 确保自定义属性正确设置

所有玩家进入大厅时,必须同步设置status属性:

// 在玩家设置昵称并进入大厅的代码中添加
PhotonNetwork.LocalPlayer.SetCustomProperties(new ExitGames.Client.Photon.Hashtable() { { "status", "lobby" } });

3. 添加Photon回调实现实时刷新

注册Photon的大厅玩家进出回调,自动刷新列表。

修改后的完整代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Photon.Pun;
using Photon.Realtime;

public class PlayerListPopUp : MonoBehaviourPunCallbacks // 继承MonoBehaviourPunCallbacks以使用回调
{
    public Transform playerListContent;
    public GameObject playerPrefab;
    public GameObject playerListPanel;
    public Button openButton;

    private void Start()
    {
        openButton.onClick.AddListener(ShowPlayerList);
        playerListPanel.SetActive(false);
        // 进入大厅时设置自身状态
        if (PhotonNetwork.InLobby)
        {
            PhotonNetwork.LocalPlayer.SetCustomProperties(new ExitGames.Client.Photon.Hashtable() { { "status", "lobby" } });
        }
    }

    private void ShowPlayerList()
    {
        playerListPanel.SetActive(true);
        ClearPlayerList();

        if (!PhotonNetwork.IsConnected || !PhotonNetwork.InLobby) return;

        // 获取大厅内的所有其他玩家
        foreach (Player player in PhotonNetwork.PlayerListOthersInLobby)
        {
            if (player.Room != null) continue;
            // 验证状态属性,兼容未设置的情况
            if (player.CustomProperties.TryGetValue("status", out object status) && status.ToString() == "lobby")
            {
                Debug.Log("大厅玩家: " + player.NickName);
                GameObject item = Instantiate(playerPrefab, playerListContent);
                item.GetComponent<PlayerNameInvite>().SetUp(player);
                
                // 绑定邀请按钮事件
                Button inviteButton = item.transform.Find("InviteButton")?.GetComponent<Button>();
                if (inviteButton != null)
                {
                    inviteButton.onClick.AddListener(() => OnInviteButtonClick(player));
                }
            }
        }

        // 可选:添加自身到列表(如果需要显示自己)
        Player localPlayer = PhotonNetwork.LocalPlayer;
        if (localPlayer.Room == null && localPlayer.CustomProperties.TryGetValue("status", out object localStatus) && localStatus.ToString() == "lobby")
        {
            GameObject item = Instantiate(playerPrefab, playerListContent);
            item.GetComponent<PlayerNameInvite>().SetUp(localPlayer);
        }
    }

    private void ClearPlayerList()
    {
        foreach (Transform child in playerListContent)
        {
            Destroy(child.gameObject);
        }
    }

    private void OnInviteButtonClick(Player player)
    {
        Debug.Log("邀请玩家: " + player.NickName);
        // 实现邀请逻辑:比如发送Photon自定义事件,或者使用房间邀请API
        // PhotonNetwork.InvitePlayer(player.NickName, PhotonNetwork.CurrentRoom.Name, "邀请你加入房间");
    }

    private void HidePlayerList()
    {
        playerListPanel.SetActive(false);
    }

    // 大厅内有玩家进入时自动刷新列表
    public override void OnPlayerEnteredLobby(Player newPlayer)
    {
        if (playerListPanel.activeSelf)
        {
            ShowPlayerList();
        }
    }

    // 大厅内有玩家离开时自动刷新列表
    public override void OnPlayerLeftLobby(Player otherPlayer)
    {
        if (playerListPanel.activeSelf)
        {
            ShowPlayerList();
        }
    }

    // 自身离开房间回到大厅时,重新设置状态并刷新
    public override void OnLeftRoom()
    {
        PhotonNetwork.LocalPlayer.SetCustomProperties(new ExitGames.Client.Photon.Hashtable() { { "status", "lobby" } });
        if (playerListPanel.activeSelf)
        {
            ShowPlayerList();
        }
    }
}

额外注意事项

  • 确保PlayerNameInvite脚本正确接收Player对象并显示昵称。
  • 玩家进入房间后,记得将status属性改为in_room,避免被大厅列表误显示:
// 在玩家加入房间的回调中添加
public override void OnJoinedRoom()
{
    PhotonNetwork.LocalPlayer.SetCustomProperties(new ExitGames.Client.Photon.Hashtable() { { "status", "in_room" } });
}

内容的提问来源于stack exchange,提问作者Hyera Hyera

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 21:54:55