Photon多人回合制游戏中按玩家顺序启用禁用按钮的实现问题
6人Photon回合制按钮控制实现方案
以下是符合需求的完整可运行代码,不需要依赖PhotonView组件,仅通过房间自定义属性实现全客户端同步:
using UnityEngine; using UnityEngine.UI; using Photon.Pun; using Photon.Realtime; using System.Linq; public class GameManager : MonoBehaviourPunCallbacks { // 提前在Unity Inspector中绑定对应的UI组件 public Button turnButton; public Text playerNameText; // 自定义属性的全局统一键名,不要随意修改 private const string TURN_ACTOR_KEY = "CurrentTurnActorId"; private void Start() { // 所有客户端默认先隐藏按钮,避免初始状态异常 turnButton.gameObject.SetActive(false); // 仅房主初始化回合属性,初始回合默认是房主 if (PhotonNetwork.IsMasterClient) { ExitGames.Client.Photon.Hashtable initProps = new ExitGames.Client.Photon.Hashtable(); initProps.Add(TURN_ACTOR_KEY, PhotonNetwork.MasterClient.ActorNumber); PhotonNetwork.CurrentRoom.SetCustomProperties(initProps); } } // 按钮点击回调,仅当前回合玩家可见按钮并可触发 public void OnTurnButtonClicked() { // 先禁用自身按钮防止重复点击 turnButton.gameObject.SetActive(false); // 获取所有在线玩家并按ActorNumber升序排序 var sortedPlayers = PhotonNetwork.PlayerList.OrderBy(p => p.ActorNumber).ToList(); // 找到当前回合玩家在排序后列表中的索引 int currentTurnId = (int)PhotonNetwork.CurrentRoom.CustomProperties[TURN_ACTOR_KEY]; int currentIndex = sortedPlayers.FindIndex(p => p.ActorNumber == currentTurnId); // 计算下一名玩家的索引,遍历到末尾则自动循环回第一个玩家 int nextIndex = (currentIndex + 1) % sortedPlayers.Count; int nextActorId = sortedPlayers[nextIndex].ActorNumber; // 更新房间自定义属性,触发所有客户端同步回合状态 ExitGames.Client.Photon.Hashtable newProps = new ExitGames.Client.Photon.Hashtable(); newProps.Add(TURN_ACTOR_KEY, nextActorId); PhotonNetwork.CurrentRoom.SetCustomProperties(newProps); } // 房间属性变更回调,所有客户端都会自动收到该通知 public override void OnRoomPropertiesUpdate(ExitGames.Client.Photon.Hashtable propertiesThatChanged) { // 仅处理回合属性变更的情况 if (propertiesThatChanged.ContainsKey(TURN_ACTOR_KEY)) { int currentActorId = (int)propertiesThatChanged[TURN_ACTOR_KEY]; Player currentPlayer = PhotonNetwork.CurrentRoom.GetPlayer(currentActorId); // 同步更新当前回合玩家的昵称显示 playerNameText.text = $"{currentPlayer.NickName} it's your turn"; // 仅当前回合的本地玩家显示可点击按钮 turnButton.gameObject.SetActive(PhotonNetwork.LocalPlayer.ActorNumber == currentActorId); } } }
注意事项
- 如果你的项目禁用了Linq,可以自行编写排序逻辑替换
OrderBy方法 - 要处理玩家中途退出的场景,排序玩家时增加过滤条件即可:
PhotonNetwork.PlayerList.Where(p => !p.IsInactive).OrderBy(p => p.ActorNumber).ToList() - 需要在Inspector中将按钮的点击事件绑定到
OnTurnButtonClicked方法
内容的提问来源于stack exchange,提问作者Shem Tom
相关产品推荐
相关产品推荐

