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

使用OnPhotonSerializeView无法跨网络同步Bool值求助

解决Photon中Bool值跨网络同步失败的问题

问题根源分析

  1. 发送端脚本:OnPhotonSerializeView仅实现数据发送逻辑,缺少接收逻辑,导致非拥有者客户端的该对象无法同步变量值;修改变量时未验证对象所有权,可能引发多端数据冲突。
  2. 接收端脚本:错误实现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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 05:45:39