如何获取其他玩家PhotonView调用RPC实现多人抓人游戏重置
多人抓人游戏全员重置逻辑实现问题
问题背景
一周前才开始学习C#编程,若问题较为基础还请谅解。
我正在开发多人抓人(Tag)游戏,目前抓人标记功能已正常运行,当前需要实现游戏重置重启逻辑:我通过玩家PhotonView的Tag.Length统计已被标记的玩家数量。
已定义变量
private GameObject[] UnTaggedPlayers;public PhotonView Player;
现有功能代码
public void OnTagged() { //Flag as tagged _isTagged = true; //Touchbacks countdown _touchbackCountDown = _touchBackDuration; GetComponentInChildren<SkinnedMeshRenderer>().material = _InfectionMat; tagged.Play(); Player.tag = "Tagged"; } [PunRPC] public void OnUnTagged() { //Flag as tagged _isTagged = false; //Change the color of player GetComponentInChildren<SkinnedMeshRenderer>().material = _initialMat; GetComponentInChildren<SkinnedMeshRenderer>().material.color = _initialColor; Player.tag = "NotTagged"; } public void Update() { UnTaggedPlayers = GameObject.FindGameObjectsWithTag("NotTagged"); if (photonView.IsMine) { if (_touchbackCountDown > 0f) { _touchbackCountDown -= Time.deltaTime; } } } private void OnTriggerEnter(Collider other) { var otherPlayer = other.GetComponentInParent<TagManager>(); if (otherPlayer != null) if (_isTagged && _touchbackCountDown <= 0f) { if(UnTaggedPlayers.Length <= 0) { //Untag Everyone } else { otherPlayer.photonView.RPC("OnTagged", RpcTarget.AllBufferedViaServer); } } } }
待实现需求
需要实现代码中//Untag Everyone注释对应的全员取消标记逻辑,找到获取所有玩家PhotonView并向其发送Untag对应RPC的方法。
实现方案
核心逻辑说明
Photon PUN开发多人同步逻辑时,状态修改类逻辑统一由房主(MasterClient)作为权威端触发,可以避免多客户端重复调用导致的状态错乱。不需要手动遍历PhotonView列表,直接查找场景中所有挂载了TagManager组件的玩家对象,逐个发送OnUnTagged的RPC即可完成全员同步重置。
另外现有代码里每帧在Update中调用GameObject.FindGameObjectsWithTag是全场景遍历操作,性能开销很高,建议后续移到玩家标记状态变化的回调中执行计数更新,不要每帧查询。
替换//Untag Everyone位置的代码
if (UnTaggedPlayers.Length <= 0) { // 仅房主触发重置,避免多端重复执行 if (PhotonNetwork.IsMasterClient) { // 拉取所有挂载TagManager的玩家实例 TagManager[] allPlayerScripts = FindObjectsOfType<TagManager>(); // 遍历给所有玩家发送取消标记的RPC,全客户端同步状态 foreach (TagManager player in allPlayerScripts) { player.photonView.RPC(nameof(OnUnTagged), RpcTarget.AllBufferedViaServer); } // 可选:重置后随机指定下一局的初始抓人者 int newSeekerIndex = Random.Range(0, allPlayerScripts.Length); allPlayerScripts[newSeekerIndex].photonView.RPC(nameof(OnTagged), RpcTarget.AllBufferedViaServer); } }
方案优势
- 用
FindObjectsOfType<TagManager>()查找玩家比通过Tag查找更准确,不会把场景内其他带同名Tag的无关对象计入统计 - 用
nameof(OnUnTagged)代替硬编码方法名字符串,后续修改方法名时不会出现RPC匹配失败的问题 - 房主权威触发逻辑,同步稳定性更高,不会出现多客户端同时重置的冲突问题
内容的提问来源于stack exchange,提问作者CorMemory
相关产品推荐
相关产品推荐

