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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 01:45:04