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

使用Photon-PUN开发多人游戏时Player1无法看到Player2的问题

问题解决指南

问题1:创建房间的Player1无法看到加入的Player2

核心原因

Player预制体未放置在Resources目录下,导致其他客户端无法通过PhotonNetwork.Instantiate加载并生成玩家实例;或Player预制体缺失PhotonView组件,无法完成网络同步。

修复步骤

  1. 调整预制体路径
    • 在Unity项目中创建Resources文件夹(若不存在),将Player预制体移入该文件夹。PhotonNetwork.Instantiate仅能加载Resources目录下的资源,否则其他客户端无法生成对应玩家实例。
  2. 配置PhotonView组件
    • 给Player预制体添加PhotonView组件:
      • 在"Observed Components"列表中添加PlayerController,让Photon自动同步该组件的序列化数据。
      • 确保PhotonView的"View ID"设置为"Auto Assign"(默认值即可)。

问题2:移动Player2时触发Received OnSerialization for view ID XXXX警告

核心原因

Player1客户端未生成Player2的实例,导致收到Player2的同步数据时找不到对应PhotonView;同时未实现玩家位置/旋转的网络同步逻辑,引发序列化异常。

修复步骤

  1. 实现IPunObservable接口同步玩家状态
    修改PlayerController代码,添加位置和旋转的网络同步逻辑,确保远程客户端能正确同步玩家移动:
using UnityEngine;
using Photon.Pun;

public class PlayerController : MonoBehaviourPunCallbacks, IPunObservable
{
    public float speed;
    public float rotSpeed;

    private Vector3 targetPosition;
    private Quaternion targetRotation;

    void Start()
    {
        if (!photonView.IsMine)
        {
            GetComponentInChildren<Camera>().enabled = false;
            GetComponentInChildren<AudioListener>().enabled = false;
            targetPosition = transform.position;
            targetRotation = transform.rotation;
        }
    }

    void Update()
    {
        if (photonView.IsMine)
        {
            // 本地玩家移动逻辑保持不变
            if (Input.GetKey(KeyCode.W)) transform.position += transform.forward * speed * Time.deltaTime;
            if (Input.GetKey(KeyCode.S)) transform.position += -transform.forward * speed * Time.deltaTime;
            if (Input.GetKey(KeyCode.A)) transform.Rotate(0, -rotSpeed * Time.deltaTime, 0);
            if (Input.GetKey(KeyCode.D)) transform.Rotate(0, rotSpeed * Time.deltaTime, 0);
        }
        else
        {
            // 平滑同步远程玩家的位置和旋转
            transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * 5f);
            transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, Time.deltaTime * 5f);
        }
    }

    // 实现序列化同步逻辑
    public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
        if (stream.IsWriting)
        {
            // 本地玩家发送位置和旋转数据
            stream.SendNext(transform.position);
            stream.SendNext(transform.rotation);
        }
        else
        {
            // 远程玩家接收并存储同步数据
            targetPosition = (Vector3)stream.ReceiveNext();
            targetRotation = (Quaternion)stream.ReceiveNext();
        }
    }
}
  1. 修正NetworkManager连接逻辑
    原代码中连接后立刻判断PhotonNetwork.IsConnected是异步操作的错误用法,修改为在回调中确认连接:
public void Connect(){
    if (!PhotonNetwork.IsConnected)
    {
        PhotonNetwork.ConnectUsingSettings();
    }
}

public override void OnConnectedToMaster(){
    Debug.Log("Server Connected");
    PhotonNetwork.JoinLobby();
}

额外检查项

  • 确保所有客户端使用相同的Photon App ID,避免跨服务器连接。
  • 游戏场景加载完成后,GameManager的Start方法会自动为每个客户端实例化本地玩家,无需额外修改该逻辑。

内容的提问来源于stack exchange,提问作者Rakesh Kr Yadav

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 20:27:04