使用OnPhotonSerializeView无法跨网络同步Bool值求助
解决Photon中Bool值跨网络同步失败的问题
问题根源分析
- 发送端脚本:
OnPhotonSerializeView仅实现数据发送逻辑,缺少接收逻辑,导致非拥有者客户端的该对象无法同步变量值;修改变量时未验证对象所有权,可能引发多端数据冲突。 - 接收端脚本:错误实现
IPunObservable接口,该接口用于同步当前挂载对象的变量,而非监听其他对象的同步数据,逻辑完全错位。
修复后的发送端脚本(Between_O_and_F_script.cs)
using System.Collections; using System.Collections.Generic; using UnityEngine; using Photon.Pun; public class Between_O_and_F_script : MonoBehaviourPun, IPunObservable { [SerializeField] public bool between_O_and_F; private PhotonView view; void Start() { view = GetComponent<PhotonView>(); } public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) { if (stream.IsWriting) { // 拥有者客户端发送变量值 stream.SendNext(between_O_and_F); } else { // 非拥有者客户端接收同步的变量值 between_O_and_F = (bool)stream.ReceiveNext(); } } private void OnTriggerEnter(Collider other) { // 仅允许对象拥有者修改变量,避免多端冲突 if (view.IsMine) { Debug.Log("entered between O and F"); between_O_and_F = true; } } private void OnTriggerExit(Collider other) { // 仅允许对象拥有者修改变量 if (view.IsMine) { between_O_and_F = false; } } }
修复后的接收端脚本(Win_check_lense.cs)
using System.Collections; using System.Collections.Generic; using UnityEngine; using Photon.Pun; public class Win_check_lense : MonoBehaviour { private string currentpos = ""; // 在Inspector面板拖拽挂载了Between_O_and_F_script的对象赋值 [SerializeField] private Between_O_and_F_script betweenScript; // 记录上一帧变量值,用于检测变化 private bool lastBetweenValue; void Start() { string lense = "convex"; string[] positions = { "Object beyond 2F", "Object at 2F", "Object between F and 2F", "Object between O and F" }; string element = positions[Random.Range(0, positions.Length)]; currentpos = element; if (betweenScript != null) { lastBetweenValue = betweenScript.between_O_and_F; } } void Update() { if (betweenScript == null) return; // 检测变量是否发生变化 if (betweenScript.between_O_and_F != lastBetweenValue) { lastBetweenValue = betweenScript.between_O_and_F; recbool(); Debug.Log("同步后的between_O_and_F值:" + lastBetweenValue); } } private void recbool() { if (betweenScript.between_O_and_F) { Debug.Log("correct"); } Debug.Log("当前between_O_and_F状态:" + betweenScript.between_O_and_F); } }
额外注意事项
- 确保发送端对象的
PhotonView组件已将Between_O_and_F_script添加到观察列表中。 - 在接收端脚本的Inspector面板,将对应游戏对象拖拽到
betweenScript字段建立引用。 - 确认触发器的
Collider已勾选IsTrigger,且触发对象拥有Rigidbody组件(Photon需刚体保证网络触发事件的正确性)。
内容的提问来源于stack exchange,提问作者laos
相关产品推荐
相关产品推荐

