轮到您启用和禁用按钮

Posted

技术标签:

【中文标题】轮到您启用和禁用按钮【英文标题】:Enable & Disable Button On your Turn 【发布时间】:2021-12-19 08:08:20 【问题描述】:

我正在尝试配置这种类型的游戏,其中我有 6 名玩家连接到同一个房间。在游戏开始时,主客户端(第一个玩家回合)开始,UI 按钮应该只对他启用,并且应该对所有其他玩家禁用,并且在第一个玩家单击按钮后它将被禁用,并且只有第二个玩家它应该对所有其他玩家启用等等。

所以我有一个想法,当第一个或主客户端单击按钮时,循环应该遍历玩家列表,然后 getNext() 是根据演员编号的下一个玩家。问题是我如何输入代码? 还建议我使用自定义属性,但这对我来说是个大问题,因为我不理解它们。看了一些教程和一些文档,但我似乎不明白。 我目前没有使用 photonview 组件。

让我写一个简短的代码来表达我的意思;

    public class GameManager : MonoBehaviourPunCallbacks
    
        private ExitGames.Client.Photon.Hashtable _myCustomProperties = new ExitGames.Client.Photon.Hashtable();

        private void Start()
        
          //onstart the master client should only be the one t view the button and click it
          //his name should be displayed when it his turn

          if (PhotonNetwork.IsMasterClient)
          
          Player_Name.text = PhotonNetwork.MasterClient.NickName + " " + "it's your turn";
          button.SetActive(true);
          

        

        //onclcik the Button
        public void TurnButton()
        
            
            for(int i = 0; i<PhotonNetwork.Playerlist.length; i++)
             
              //so every click of the button a loop should iterate and check the player if is the next to see the button and click it
             //a name should also be displayed on his turn as per his nickname

             
        

    

【问题讨论】:

【参考方案1】:

这里不需要自定义播放器属性。

我宁愿为此使用房间属性

public class GameManager : MonoBehaviourPunCallbacks

    private const string ACTIVE_PLAYER_KEY = "ActivePlayer";
    private const string ACTIVE_ME_FORMAT = "0, you it's your turn!!";
    private const string ACTIVE_OTHER_FORMAT = "Please wait, it's 0's turn ...";

    private Room room;

    [SerializeField] private Button button;
    [SerializeField] private Text Player_Name;

    #region MonoBehaviourPunCallbacks

    private void Awake()
    
        button.onClick.AddListener(TurnButton):
        button.gameObject.SetActive(false);

        Player_Name.text = "Connecting ...";

        // Store the current room
        room = PhotonNetwork.CurrentRoom;

        if (PhotonNetwork.IsMasterClient)
        
            // As master go active since usually this means you are the first player in this room

            // Get your own ID
            var myId = PhotonNetwork.LocalPlayer.ActorNumber;
            // and se it to active
            SetActivePlayer(myId);
        
        else
        
            // Otherwise fetch the active player from the room properties
            OnRoomPropertiesUpdate(room.CustomProperties);
        
    

    // listen to changed room properties - this is always called if someone used "SetCustomProperties" for this room
    // This is basically the RECEIVER and counter part to SetActivePlayer below
    public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
    
        // Maybe another property was changed but not the one we are interested in
        if(!propertiesThatChanged.TryGetValue(ACTIVE_PLAYER_KEY, out var newActiveID)) return;

        // if we got a value but it's not an int something is wrong in general
        if(!(newActiveID is int newActvieIDValue))
        
            Debug.LogError("For some reason \"ACTIVE_PLAYER_KEY\" is not an int!?");
            return;
        

        // otherwise apply the ID
        ApplyActivePlayer(newActvieIDValue);
    

    // Optional but might be important (?)
    // In the rare case that the currently active player suddenly leaves for whatever reason
    // as the master client you might want to handle this and go to the next player then
    //public override void OnPlayerLeftRoom (Player otherPlayer) 
    //
    //    if(!PhotonNetwork.IsMasterClient) return;
    //
    //    if(!propertiesThatChanged.TryGetValue(ACTIVE_PLAYER_KEY, out var currentActiveID) && currentActiveID is int currentActiveIDValue) return;
    //
    //    if(currentActiveIDValue != otherPlayer.ActorNumber) return;
    //
    //    var nextPlayer = Player.GetNextFor(currentActiveIDValue);
    //    var nextPlayerID = nextPlayer.ActorNumber;
    //    SetActivePlayer(nextPlayerID);
    //

    #endregion MonoBehaviourPunCallbacks

    // Called via onClick
    private void TurnButton()
    
        // this gets the next player after you sorted by the actor number (=> order they joined the room)
        // wraps around at the end
        var nextPlayer = Player.GetNext();
        // Get the id
        var nextPlayerID = nextPlayer.ActorNumber;
        // and tell everyone via the room properties that this is the new active player
        SetActivePlayer(nextPlayerID);
    

    // This writes the new active player ID into the room properties
    // You can see this as kind of SENDER since the room properties will be updated for everyone
    private void SetActivePlayer(int id)
    
        var hash = new ExitGames.Client.Photon.Hashtable();
        hash[ACTIVE_PLAYER_KEY] = id;
        room.SetCustomProperties(hash);
    

    // this applies all local changes according to the active player
    private void ApplyActivePlayer(int id)
    
        // get the according player
        var activePlayer = Player.Get(id);

        // Am I this player?
        var iAmActive = PhotonNetwork.LocalPlayer.ActorNumber == id;

        // Set the button active/inactive accordingly
        button.gameObject.SetActive(iAmActive);

        // Set the text accordingly
        Player_Name.text = string.Format(iAmActive ? ACTIVE_ME_FORMAT : ACTIVE_OTHER_FORMAT, activePlayer.NickName):
    

【讨论】:

您的代码出现了一些错误! room.SetCustomProperties(new Hashtable(ACTIVE_PLAYER_KEY, id)); Hashtable 不包含带有 2 个参数的构造函数!还有room.BroadcastPropertiesChangeToAll = true; 属性或索引器“Room.BroadcastPropertiesChangeToAll”不能分配给——它是只读的 @ShemTom 更新了BroadcastPropertiesChangeToAll 的代码(在智能手机上输入;))我认为无论如何它都应该是默认值,否则在创建房间 想问一下为什么我们调用onjoined room 并且玩家已经在房间里了。我已经设置了一个大厅场景和脚本来管理它,所以目前,游戏管理器脚本(上面的脚本)在玩家已经在房间里之后在另一个场景中被调用!不幸的是,脚本没有相应地工作!我尝试输入一些 debug.logs 但它们没有显示!它卡在清醒的部分! 在这种情况下,只需将所有内容从OnJoinedRoom 移动到底部的Awake 当房间中的某个 bool 设置为 true 时,我将如何禁止轮到下一个玩家? if(room.CustomProperties.ContainsKey(IS_SHOT_KEY) &amp;&amp; (bool)room.CustomProperties[IS_SHOT_KEY]) Debug.Log("Don't move to next player"); else SetActivePlayer(nextPlayerID);

以上是关于轮到您启用和禁用按钮的主要内容,如果未能解决你的问题,请参考以下文章

禁用和启用 html 输入按钮

隐藏/显示和启用/禁用按钮?

通过删除属性启用和禁用按钮[重复]

使用 javascript 和 asp.net 启用和禁用按钮

jQuery 禁用启用按钮样式

动态启用和禁用切换按钮