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

Photon多人系统中Start()被调用两次的问题求助

问题解决:Photon多人游戏中Start()重复调用导致的日志/实例化重复

核心原因

  1. 每个客户端加载场景时,都会执行场景中MPRoomServer脚本的Start()方法,而PhotonNetwork.Instantiate是网络同步方法,会在所有客户端创建实例,叠加后导致重复。
  2. 若MPRoomServer所在GameObject带有PhotonView组件,Photon可能会在网络同步时生成该对象的副本,导致脚本被两次初始化。

解决方案

方案1:仅让Master Client执行全局实例化逻辑

火箭这类全局场景对象,只需要由房间的Master Client创建一次,所有客户端会自动同步该实例。修改Start()方法,加入Master Client判断:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using TMPro;
public class MPRoomServer : MonoBehaviour
{
    public GameObject rocket;
    public TMP_Text title;

    void Start()
    {
        // 仅在Master Client执行全局实例化
        if (PhotonNetwork.IsMasterClient)
        {
            PhotonNetwork.Instantiate(rocket.name, new Vector3(20.4928417f,4.3900001f,-10.116004f), Quaternion.identity);
        }
        
        // 每个客户端仅更新自己本地的UI
        title.text = "Room " + PhotonNetwork.CurrentRoom.Name;
        // 仅在本地客户端打印日志,避免重复输出
        Debug.Log($"Local player joined: {PhotonNetwork.LocalPlayer.NickName}");
    }
}

方案2:避免场景对象的网络重复同步

如果MPRoomServer所在GameObject带有PhotonView组件,需要:

  • 确保该对象的PhotonView组件中,Instantiation设置为"Manual Instantiation"
  • 或者移除PhotonView组件,将该对象标记为只在本地存在,仅让每个客户端独立处理本地UI逻辑,全局实例化逻辑交给Master Client。

方案3:使用Photon的回调替代Start()

改用Photon提供的网络回调方法,比如OnJoinedRoom(),确保逻辑只在玩家成功加入房间时执行一次:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
public class MPRoomServer : MonoBehaviourPunCallbacks
{
    public GameObject rocket;
    public TMP_Text title;

    void Start()
    {
        // 保留本地UI初始化,避免依赖回调时机
        title.text = "Room " + PhotonNetwork.CurrentRoom.Name;
    }

    // 玩家成功加入房间时的回调,仅执行一次
    public override void OnJoinedRoom()
    {
        if (PhotonNetwork.IsMasterClient)
        {
            PhotonNetwork.Instantiate(rocket.name, new Vector3(20.4928417f,4.3900001f,-10.116004f), Quaternion.identity);
        }
        Debug.Log($"New player joined: {PhotonNetwork.LocalPlayer.NickName}");
    }
}

关键注意点

  • PhotonNetwork.Instantiate会自动在所有客户端同步创建对象,不要在每个客户端都调用,否则会导致N个客户端创建N次,最终出现N²个实例。
  • 区分全局逻辑(仅Master Client执行)和本地逻辑(每个客户端执行),避免重复执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 13:54:21