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

Unity Photon PUN非主客户端GameOver RPC空引用异常求助

问题定位与修复方案

核心问题

非主客户端执行Gameover RPC时,GameManager.cs第360行的score.player.NickName触发空引用异常,本质是非主客户端的score.player引用为null。

触发原因

  1. 数据同步缺失:PlayerScore中的player(PhotonPlayer对象)仅在主客户端本地初始化,未通过Photon RPC或PhotonView同步到非主客户端,导致非主客户端无法获取有效引用。
  2. 对象生命周期问题:游戏结束时,部分玩家对象已被提前销毁,score.player指向已释放的内存地址。

修复方案

方案1:直接存储玩家昵称,避免依赖PhotonPlayer引用

修改PlayerScore类,不再持有PhotonPlayer引用,而是直接存储昵称字符串:

public class PlayerScore
{
    public string NickName { get; private set; }
    public int Score { get; private set; }

    public PlayerScore(string nickName, int score)
    {
        NickName = nickName;
        Score = score;
    }
}

主客户端在收集分数时直接获取玩家昵称并封装到PlayerScore,再通过RPC同步整个列表,非主客户端直接读取NickName字段即可,彻底规避空引用风险。

方案2:通过ActorNumber同步玩家信息

在Gameover RPC中,传递玩家的ActorNumber而非完整PlayerScore对象,非主客户端根据ActorNumber查找有效PhotonPlayer:

// 主客户端调用RPC
photonView.RPC("RPC_Gameover", RpcTarget.All, 
    PhotonNetwork.PlayerList.Select(p => p.ActorNumber).ToArray(),
    playerScores.Select(s => s.Score).ToArray());

// GameManager中的RPC方法
[PunRPC]
private void RPC_Gameover(int[] actorNumbers, int[] scores)
{
    for (int i = 0; i < actorNumbers.Length; i++)
    {
        PhotonPlayer player = PhotonNetwork.PlayerList.FirstOrDefault(p => p.ActorNumber == actorNumbers[i]);
        if (player == null)
        {
            Debug.LogWarning($"未找到ActorNumber为{actorNumbers[i]}的玩家");
            continue;
        }
        // 使用player.NickName和scores[i]进行后续逻辑
    }
}

方案3:添加空引用防御检查(快速临时修复)

在访问score.player.NickName前添加空判断,避免异常抛出:

// GameManager.cs第360行修改
if (score != null && score.player != null)
{
    string playerNick = score.player.NickName;
    // 原有逻辑
}
else
{
    Debug.LogWarning("跳过无效的玩家分数条目");
}

内容的提问来源于stack exchange,提问作者Finalbi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 06:11:03