Unity Photon无PhotonView时向主客户端发送玩家入房消息的方案求助
解决方法
问题核心是:只有新加入的玩家会触发自身的OnJoinedRoom刷新列表,房间内已有的玩家不会收到通知更新列表,导致老玩家的列表停留在自己加入时的状态。
无需RPC或RaiseEvent,直接利用Photon自带的玩家回调就能解决,具体修改如下:
确保脚本继承
MonoBehaviourPunCallbacks,重写OnPlayerEnteredRoom和OnPlayerLeftRoom方法,处理玩家加入/离开的列表更新。保留原
OnJoinedRoom的全量初始化逻辑(新玩家加入时本地PlayerList是完整的,初始化全量列表是正确的):
public override void OnJoinedRoom() { _roomNameText.text = "Комната: " + PhotonNetwork.CurrentRoom.Name; MenuManager.instance.OpenMenu("Room"); // 清空原有列表,初始化所有玩家 for (int i = 0; i < _playerList.childCount; i++) { Destroy(_playerList.GetChild(i).gameObject); } foreach (var player in PhotonNetwork.PlayerList) { Instantiate(_playerNamePrefab, _playerList).GetComponent<PlayerListItem>().SetUp(player); Debug.Log($"{player.NickName} connected"); } _startGameButton.SetActive(PhotonNetwork.IsMasterClient); }
- 添加
OnPlayerEnteredRoom回调,让老玩家的列表新增新加入的玩家:
public override void OnPlayerEnteredRoom(Player newPlayer) { // 仅添加新玩家,不改动原有列表 Instantiate(_playerNamePrefab, _playerList).GetComponent<PlayerListItem>().SetUp(newPlayer); Debug.Log($"{newPlayer.NickName} joined the room"); }
- 可选:添加
OnPlayerLeftRoom回调,处理玩家离开时移除对应列表项:
public override void OnPlayerLeftRoom(Player otherPlayer) { // 遍历找到对应玩家的列表项并销毁 foreach (Transform child in _playerList) { var playerItem = child.GetComponent<PlayerListItem>(); if (playerItem != null && playerItem.Player == otherPlayer) { Destroy(child.gameObject); break; } } Debug.Log($"{otherPlayer.NickName} left the room"); }
- 额外处理主客户端切换,确保开始按钮状态正确:
public override void OnMasterClientSwitched(Player newMasterClient) { _startGameButton.SetActive(PhotonNetwork.IsMasterClient); }
逻辑说明
- 新玩家加入时,自身
OnJoinedRoom触发,本地PhotonNetwork.PlayerList包含所有玩家,初始化全量列表即可同步所有玩家信息。 - 房间内老玩家会触发
OnPlayerEnteredRoom,仅添加新玩家项,不会重复生成原有玩家。 - 这样所有客户端的玩家列表会保持完全同步,不会出现老玩家看不到新玩家、新玩家能看到所有人的不对称问题。
内容的提问来源于stack exchange,提问作者Калашников Ян
相关产品推荐
相关产品推荐

