轮到您启用和禁用按钮
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) && (bool)room.CustomProperties[IS_SHOT_KEY]) Debug.Log("Don't move to next player"); else SetActivePlayer(nextPlayerID);
以上是关于轮到您启用和禁用按钮的主要内容,如果未能解决你的问题,请参考以下文章