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

Photon RPC传GameObject报Custom type not found错误

问题背景

使用Photon PUN进行Unity多人联机开发时,碰撞触发逻辑中调用RPC传入GameObject参数,运行时抛出序列化异常。
原实现代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;

public class FinishManager : MonoBehaviour
{
    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag("Legs"))
        {
            collision.gameObject.GetComponent<PhotonView>().RPC("Win", RpcTarget.All, collision.gameObject); /*报错行*/
        }
    }


    [PunRPC]
    public void Win(GameObject player)
    {
        PhotonNetwork.Destroy(player);
    }

}
核心报错
Exception: Write failed. Custom type not found: UnityEngine.GameObject

错误栈最终指向RPC调用行,传入collision.gameObject参数时触发序列化失败。

问题原因

Photon PUN的RPC参数传输依赖内置序列化规则,默认不支持直接传递UnityEngine.GameObject类型,协议层无法识别该类型的序列化/反序列化逻辑,因此写入网络流时直接抛出异常。
另外原代码还存在隐藏逻辑问题:调用的是碰撞到的Legs物体挂载的PhotonView发RPC,但Win方法定义在FinishManager组件上,如果Legs物体未挂载FinishManager,就算序列化正常也会触发“找不到目标RPC方法”的错误。

修复方案

所有Photon网络物体上的PhotonView都有全局唯一、全客户端同步的ViewID(int类型,属于Photon原生支持序列化的基础类型),不需要传递GameObject实例,传递ViewID即可在所有客户端定位到目标物体。
修正后可直接运行的代码:

using UnityEngine;
using Photon.Pun;

public class FinishManager : MonoBehaviourPun
{
    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag("Legs"))
        {
            PhotonView targetPhotonView = collision.gameObject.GetComponent<PhotonView>();
            // 传递int类型的ViewID,无序列化问题
            photonView.RPC("Win", RpcTarget.All, targetPhotonView.ViewID);
        }
    }

    [PunRPC]
    public void Win(int targetViewID)
    {
        // 所有客户端通过统一的ViewID找到对应网络物体
        PhotonView targetView = PhotonNetwork.GetPhotonView(targetViewID);
        if (targetView != null)
        {
            PhotonNetwork.Destroy(targetView.gameObject);
        }
    }
}

额外注意事项

  • Photon RPC原生支持传参类型仅包含基础值类型(int/float/bool/string等)、Unity常用值类型(Vector2/Vector3/Quaternion等)、Photon内置类型(Player/PhotonView等),不要直接传GameObject、Transform、自定义类实例作为参数,除非你手动注册了对应类型的自定义序列化规则。
  • 调用RPC时,要确保调用RPC的PhotonView所在物体上,挂载了包含目标[PunRPC]方法的组件,否则会找不到RPC入口。
  • 网络物体的销毁必须通过PhotonNetwork.Destroy调用,不能直接用Destroy,否则无法同步销毁状态到所有客户端。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 16:12:20