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
相关产品推荐
相关产品推荐

