PUN2中OnRoomListUpdate回调返回房间列表不准确问题求助
问题原因分析
你的核心问题是对PUN2的OnRoomListUpdate回调机制理解有误:
- PUN2传入该回调的
_roomList不是全量可用房间列表,而是增量更新集合——仅包含本次有变化的房间(新创建的、玩家数更新的、被销毁的房间)。 - 你每次调用
ClearRoomList()后直接渲染传入的_roomList,相当于只显示了本次变化的房间,旧的房间被完全清空覆盖,最终只留下最新一次更新的房间条目。 - 另外你没有处理
RoomInfo.RemovedFromList属性,无法正确移除已销毁的房间条目。
解决建议与修改代码
核心思路
维护一个本地的全量房间列表,每次回调时根据增量更新集合修改这个本地列表,最后基于本地全量列表刷新UI。
修改后的完整代码
首先在类中添加本地全量房间列表:
private List<RoomInfo> _allRooms = new List<RoomInfo>();
然后重写OnRoomListUpdate方法:
public override void OnRoomListUpdate(List<RoomInfo> _roomList) { // 处理增量更新的房间数据 foreach (RoomInfo room in _roomList) { if (room.RemovedFromList) { // 移除已被删除的房间 _allRooms.RemoveAll(r => r.Name.Equals(room.Name)); } else { // 更新或添加房间到本地列表 int existingRoomIndex = _allRooms.FindIndex(r => r.Name.Equals(room.Name)); if (existingRoomIndex != -1) { _allRooms[existingRoomIndex] = room; } else { _allRooms.Add(room); } } } // 刷新UI ClearRoomList(); foreach (RoomInfo room in _allRooms) { GameObject roomItemObj = Instantiate(roomItemPrefab, content); roomItemObj.transform.Find("Name of Room").GetComponent<TextMeshProUGUI>().text = room.Name; roomItemObj.transform.Find("players in room").GetComponent<TextMeshProUGUI>().text = $"{room.PlayerCount}/{room.MaxPlayers}"; roomItemObj.GetComponent<Button>().onClick.AddListener(() => PhotonNetwork.JoinRoom(room.Name)); } LogCurrentRoomList(); }
确保ClearRoomList方法正确实现
private void ClearRoomList() { // 遍历Content下所有子物体并销毁 foreach (Transform child in content) { Destroy(child.gameObject); } }
额外注意事项
- 房间创建时必须设置
RoomOptions.IsVisible = true和RoomOptions.IsOpen = true,否则其他实例无法发现该房间:RoomOptions options = new RoomOptions(); options.IsVisible = true; options.IsOpen = true; options.MaxPlayers = 4; // 按需设置 PhotonNetwork.CreateRoom("房间名称", options); - 所有测试实例必须连接到同一个Photon服务器区域(在PhotonServerSettings中配置),跨区域的房间无法互通。
- 确保在获取房间列表前调用
PhotonNetwork.JoinLobby(),只有进入大厅后才能接收房间列表的更新通知。
内容的提问来源于stack exchange,提问作者Dharmik Suthar
相关产品推荐
相关产品推荐

