Photon.Pun FPS游戏玩家重复生成Bug修复求助
问题描述
开发基于Photon.Pun的FPS游戏时,遇到以下问题:当房间内已有玩家时,新玩家加入后会出现其他玩家重复生成的情况。打印生成日志显示SpawnPlayer仅执行一次,推测问题出在实例化相关逻辑中。以下是RoomManager脚本:
using System.Collections; using System.Collections.Generic; using UnityEngine; using Photon.Pun; using TMPro; using Unity.VisualScripting; using Photon.Realtime; public class RoomManager : MonoBehaviourPunCallbacks { public static RoomManager instance; public GameObject player; public GameObject playersWeapon; [Space] public Transform spawnPoint; public GameObject Connectingcam; public TextMeshPro placeholderText; public string nickname; private pauseScript pauseScreenScript; [Space] public GameObject nameUI; public GameObject connectUI; void Awake() { instance = this; } public void ChangeNickname(string n) { nickname = n; } public void JoinRoomButtonPressed() { nameUI.SetActive(false); connectUI.SetActive(true); if(nickname == "") { nickname = "이름없는사용자" + Random.Range(0, 99999).ToString(); } Debug.Log("Connecting to Server"); PhotonNetwork.ConnectUsingSettings(); } // Start is called before the first frame update void Start() { } public override void OnConnectedToMaster() { base.OnConnectedToMaster(); Debug.Log("Connected to Server"); PhotonNetwork.JoinLobby(); } public override void OnJoinedLobby() { base.OnJoinedLobby(); PhotonNetwork.JoinOrCreateRoom("test", null, null); } public override void OnJoinedRoom() { Connectingcam.SetActive(false); base.OnJoinedRoom(); Debug.Log("Joined Room"); SpawnPlayer(); } // Update is called once per frame void Update() { } public override void OnDisconnected(DisconnectCause cause) { base.OnDisconnected(cause); Debug.Log("Disconnected from Server"); } public override void OnPlayerEnteredRoom(Player newPlayer) { base.OnPlayerEnteredRoom(newPlayer); } public void SpawnPlayer(){ if(PhotonNetwork.IsConnected && PhotonNetwork.LocalPlayer.IsLocal) { Debug.Log("Spawning Player"); GameObject _player = PhotonNetwork.Instantiate(player.name, spawnPoint.position, Quaternion.identity); _player.GetComponent<PlayerSetup>().IsLocalPlayer(); _player.GetComponent<HP>().IsLocalPlayer = true; _player.GetComponent<voidDeath>().IsLocalPlayer = true; _player.GetComponentInChildren<Weapon>().IsLocalPlayer = true; _player.GetComponent<PhotonView>().RPC("SetNickname", RpcTarget.AllBuffered, nickname); PhotonNetwork.LocalPlayer.NickName = nickname; Debug.Log("Spawned Player"); } } public void killPlayer() { } }
修复方案
1. 修正玩家预制体的实例化路径
PhotonNetwork.Instantiate要求预制体必须放在Resources文件夹下,且传入的是Resources内的相对路径,而非直接使用player.name。路径错误会导致Photon无法正确同步实例,引发异常生成。
修改SpawnPlayer中的实例化代码:
// 假设玩家预制体放在Resources/Players目录下,路径改为对应相对路径 GameObject _player = PhotonNetwork.Instantiate("Players/Player", spawnPoint.position, Quaternion.identity);
2. 优化本地玩家初始化逻辑
避免手动赋值IsLocalPlayer时出现范围错误,通过PhotonView.IsMine精准判断本地玩家:
public void SpawnPlayer(){ if(PhotonNetwork.IsConnected && PhotonNetwork.LocalPlayer.IsLocal) { Debug.Log("Spawning Player"); GameObject _player = PhotonNetwork.Instantiate("Players/Player", spawnPoint.position, Quaternion.identity); PhotonView playerView = _player.GetComponent<PhotonView>(); // 仅对本地玩家执行初始化操作 if(playerView.IsMine) { _player.GetComponent<PlayerSetup>().IsLocalPlayer(); _player.GetComponent<HP>().IsLocalPlayer = true; _player.GetComponent<voidDeath>().IsLocalPlayer = true; _player.GetComponentInChildren<Weapon>().IsLocalPlayer = true; playerView.RPC("SetNickname", RpcTarget.AllBuffered, nickname); PhotonNetwork.LocalPlayer.NickName = nickname; } Debug.Log("Spawned Player"); } }
3. 确保RoomManager单例不重复创建
在Awake中添加单例校验和DontDestroyOnLoad,防止场景切换时生成多个RoomManager实例,避免重复调用SpawnPlayer:
void Awake() { // 销毁重复的单例实例 if(instance != null && instance != this) { Destroy(gameObject); return; } instance = this; DontDestroyOnLoad(gameObject); }
4. 检查玩家预制体的Photon配置
- 玩家预制体必须挂载PhotonView组件,并在
Observed Components中添加需要同步的组件(如Transform、Animator),确保Photon能正确同步玩家状态,避免重复生成的假象。 - 确保预制体的PhotonView的
View ID设置为AutoSync,由Photon自动分配唯一ID。
5. 排查额外的SpawnPlayer触发逻辑
检查项目中是否有其他脚本调用了RoomManager.instance.SpawnPlayer(),比如场景加载事件、UI误触发等,确保只有OnJoinedRoom时才执行玩家生成。
内容的提问来源于stack exchange,提问作者OHHI3368
相关产品推荐
相关产品推荐

