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

房主离开Photon房间触发setProperties异常的解决方法咨询

问题解决:房主离开时SetCustomProperties触发日志异常

问题现象

将房间时长计时器设为房间属性后,房主离开房间时会触发日志异常:

Operation setProperties (252) not called because client is not connected or not ready yet, client state: Leaving

该错误不影响功能运行,但会干扰日志输出,其他玩家退出时无此问题。引发问题的核心代码如下:

private void Update()
{
    _currentPlayersCountText.text = PhotonNetwork.PlayerList.Length.ToString();

    if (PhotonNetwork.IsMasterClient)
    {
        if (PhotonNetwork.PlayerList.Length >= 5)
        {
            _startGameButton.GetComponent<Button>().enabled = true;
        }
        else
        {
            _startGameButton.GetComponent<Button>().enabled = false;
        }

        Hashtable ht = PhotonNetwork.CurrentRoom.CustomProperties;
        ht.Remove("timer");
        ht.Add("timer", _roomTimer.timeRemaining);
        PhotonNetwork.CurrentRoom.SetCustomProperties(ht);
    }

    if (_roomTimer.timeRemaining <= 110)
    {
        LeaveRoom();
    }
}

问题原因

房主执行LeaveRoom()后,客户端进入Leaving状态,但Update循环不会立即终止。此时PhotonNetwork.IsMasterClient仍可能返回true,代码会继续尝试调用SetCustomProperties,但客户端已处于断开连接的过程中,因此触发日志异常。

解决方案

1. 添加离开标记,阻止后续属性更新

在类中添加布尔变量标记是否正在离开房间,触发离开流程后跳过所有需要网络操作的逻辑:

private bool _isLeavingRoom;

private void Update()
{
    _currentPlayersCountText.text = PhotonNetwork.PlayerList.Length.ToString();

    // 已触发离开流程,跳过网络操作逻辑
    if (_isLeavingRoom) return;

    if (PhotonNetwork.IsMasterClient)
    {
        _startGameButton.GetComponent<Button>().enabled = PhotonNetwork.PlayerList.Length >= 5;

        Hashtable ht = PhotonNetwork.CurrentRoom.CustomProperties;
        ht["timer"] = _roomTimer.timeRemaining; // 直接赋值覆盖,无需先删除再添加
        PhotonNetwork.CurrentRoom.SetCustomProperties(ht);
    }

    if (_roomTimer.timeRemaining <= 110)
    {
        _isLeavingRoom = true;
        LeaveRoom();
    }
}

2. 检查客户端连接状态

在调用SetCustomProperties前,额外校验客户端是否处于正常连接状态:

if (PhotonNetwork.IsMasterClient && PhotonNetwork.NetworkClientState == ClientState.Connected)
{
    // 执行房间属性更新逻辑
}

3. 优化计时器更新频率

原代码每帧都更新房间属性属于过度调用,改为固定间隔更新(比如每0.5秒),既减少网络请求,也降低触发异常的概率:

private float _timerUpdateInterval = 0.5f;
private float _lastUpdateTime;
private Button _startGameBtn;

private void Awake()
{
    // 缓存按钮组件,避免每帧重复获取
    _startGameBtn = _startGameButton.GetComponent<Button>();
}

private void Update()
{
    _currentPlayersCountText.text = PhotonNetwork.PlayerList.Length.ToString();

    if (_isLeavingRoom) return;

    if (PhotonNetwork.IsMasterClient && PhotonNetwork.NetworkClientState == ClientState.Connected)
    {
        _startGameBtn.enabled = PhotonNetwork.PlayerList.Length >= 5;

        // 仅间隔指定时间才更新属性
        if (Time.time - _lastUpdateTime >= _timerUpdateInterval)
        {
            _lastUpdateTime = Time.time;
            Hashtable ht = PhotonNetwork.CurrentRoom.CustomProperties;
            ht["timer"] = _roomTimer.timeRemaining;
            PhotonNetwork.CurrentRoom.SetCustomProperties(ht);
        }
    }

    if (_roomTimer.timeRemaining <= 110)
    {
        _isLeavingRoom = true;
        LeaveRoom();
    }
}

额外优化点

  • 直接通过ht["timer"] = value覆盖属性,无需先Remove再Add,简化代码
  • 缓存Button组件实例,避免每帧重复调用GetComponent消耗性能

内容的提问来源于stack exchange,提问作者Калашников Ян

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 15:35:29