- Home /
Replacing existing prefab with asset id...
I'm looking at guides from DipperDino (DipperDino guide) on Mirror multiplayer and during development there was an error that it doesn't have. I rechecked everything many times and couldn't fix it. The error sounds like "replacing existing prefab with asset id", referring to objects in Rosouces.SpawnablePrefabs. I left the NetworkManagerLobby class code below.
using Mirror;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
public class NetworkManagerLobby : NetworkManager
{
[SerializeField] private int minPlayers = 2;
[Scene] [SerializeField] private string menuScene = string.Empty;
[Header("Room")]
[SerializeField] private NetworkRoomPlayerLobby roomPlayerPrefab = null;
[Header("Game")]
[SerializeField] private NetworkGamePlayerLobby gamePlayerPrefab = null;
[SerializeField] private GameObject playerSpawnSystem = null;
public static event Action OnClientConnected;
public static event Action OnClientDisconnected;
public static event Action<NetworkConnection> OnServerReadied;
public List<NetworkRoomPlayerLobby> RoomPlayers { get; } = new List<NetworkRoomPlayerLobby>();
public List<NetworkGamePlayerLobby> GamePlayers { get; } = new List<NetworkGamePlayerLobby>();
// HERE CAN BE SPECTATOR PLAYERS LIST FOR OWN SPECTATOR LOGIC (LIKE RoomPlayer -> GamePlayers BUT SpectatorPlayers -> GamePlayers
public override void OnStartServer() => spawnPrefabs = Resources.LoadAll<GameObject>("SpawnablePrefabs").ToList();
public override void OnStopServer()
{
RoomPlayers.Clear();
}
public override void OnStartClient()
{
var spawnablePrefabs = Resources.LoadAll<GameObject>("SpawnablePrefabs");
foreach (var prefab in spawnablePrefabs)
{
ClientScene.RegisterPrefab(prefab);
}
}
public override void OnClientConnect(NetworkConnection conn)
{
base.OnClientConnect(conn);
OnClientConnected?.Invoke();
}
public override void OnClientDisconnect(NetworkConnection conn)
{
base.OnClientDisconnect(conn);
OnClientDisconnected?.Invoke();
}
public override void OnServerConnect(NetworkConnection conn)
{
if (numPlayers >= maxConnections)
{
conn.Disconnect();
return;
//TODO; show err lobby is full message
}
if (SceneManager.GetActiveScene().path != menuScene)
{
conn.Disconnect();
return;
//TODO; show err scene message
}
}
public override void OnServerDisconnect(NetworkConnection conn)
{
if (conn.identity != null)
{
var player = conn.identity.GetComponent<NetworkRoomPlayerLobby>();
RoomPlayers.Remove(player);
NotifyPlayersOfReadyState();
}
base.OnServerDisconnect(conn);
}
public override void OnServerAddPlayer(NetworkConnection conn)
{
if (SceneManager.GetActiveScene().path == menuScene)
{
bool isLeader = RoomPlayers.Count == 0;
NetworkRoomPlayerLobby roomPlayerInstance = Instantiate(roomPlayerPrefab);
roomPlayerInstance.IsLeader = isLeader;
NetworkServer.AddPlayerForConnection(conn, roomPlayerInstance.gameObject);
}
}
public void NotifyPlayersOfReadyState()
{
foreach (var player in RoomPlayers)
{
player.HandleReadyToStart(IsReadyToStart());
}
}
private bool IsReadyToStart()
{
if (numPlayers < minPlayers) { return false; }
foreach (var player in RoomPlayers) //Loop every player in the lobby
{
if (!player.IsReady) { return false; }
}
//########Loop every player in the lobby########
//foreach (var player in RoomPlayers)
//{
// CODE HERE;
//}
return true;
}
public void StartGame()
{
if(SceneManager.GetActiveScene().path == menuScene)
{
if(!IsReadyToStart()) { return; }
ServerChangeScene("Scene_Tests_01");
}
}
public override void ServerChangeScene(string newSceneName)
{
// From menu to scene
if (SceneManager.GetActiveScene().path == menuScene && newSceneName.StartsWith("Scene_Tests"))
{
for (int i = RoomPlayers.Count - 1; i >= 0; i--)
{
var conn = RoomPlayers[i].connectionToClient;
var gameplayerInstance = Instantiate(gamePlayerPrefab);
gameplayerInstance.SetDisplayName(RoomPlayers[i].DisplayName);
NetworkServer.Destroy(conn.identity.gameObject);
NetworkServer.ReplacePlayerForConnection(conn, gameplayerInstance.gameObject, true);
}
}
base.ServerChangeScene(newSceneName);
}
public override void OnServerSceneChanged(string sceneName)
{
if (sceneName.StartsWith("Scene_Tests"))
{
GameObject playerSpawnSystemInstance = Instantiate(playerSpawnSystem);
NetworkServer.Spawn(playerSpawnSystemInstance);
}
}
public override void OnServerReady(NetworkConnection conn)
{
base.OnServerReady(conn);
OnServerReadied?.Invoke(conn);
}
}
I am also facing the same issue.. Leaving this comment here just so i can come back here is someone answers..
Answer by betomaluje · Dec 09, 2020 at 07:46 AM
@reseeman , @AnasHussain and @Kachimov . I'm no expert on Mirror but I also followed the same tutorial and got a bunch of warnings when going back to the lobby after a round. What I did to remove all those was basically try to clear the list whenever we start the client or server. Also I'm using the same spawnPrefabs
list for both:
...
public override void OnStartServer()
{
spawnPrefabs.Clear();
spawnPrefabs = Resources.LoadAll<GameObject>("SpawnablePrefabs").ToList();
}
public override void OnStartClient()
{
spawnPrefabs.Clear();
spawnPrefabs = Resources.LoadAll<GameObject>("SpawnablePrefabs").ToList();
ClientScene.ClearSpawners();
foreach (var prefab in spawnPrefabs)
{
ClientScene.RegisterPrefab(prefab);
}
}
...
If one hosts the game, it will call OnStartServer
and also OnStartClient
... I know it's not the best but at least now I don't have that problem of replacing prefabs
I really hope this helps and if anyone has a better approach please let us know :D
that worked for me, mostly. I had three warnings: "Empty" was replaced two times and "RoomPlayer" was replaced once. When I cleared the lists (with the edits above) two of those warnings went away. Still working to clear the third replacement now... Thanks @betomaluje !
I still have the exact same problem. Without the lines shown above I get 3 errors, 2 for player and 1 for RoomPlayer. With the lines above, I only get 1 error for the player. Did you find any solutions or workarounds?
I know I don't have the error anymore, and after looking at the code for the last ten $$anonymous$$utes I can't for the life of me remember how it was solved. :(
However, later in the tutorial, we add a NetworkRoomPlayer prefab. That might have taken care of it for me. It might be that as I moved forward in the tutorials it got cleaned up. I'm sorry to not be of more help here.
Your answer
Follow this Question
Related Questions
Unity Mirror Network Discovery Stop Joining 0 Answers
Animations playing only in the Host and not on the clients - Unity Mirror Networking. 1 Answer
Unet/Mirror. Spawn different prefab in local and server/rest of clients 0 Answers
Replacing existing prefab with asset id... 2 Answers
Unity Mirror Networkfunctions doesnt work on non-player Objects? 0 Answers