Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice

Question The ghost collection contains a ghost which does not have a valid prefab on the client

Discussion in 'NetCode for ECS' started by Jonathan_L, Oct 15, 2023.

  1. Jonathan_L

    Jonathan_L

    Joined:
    Jan 26, 2016
    Posts:
    43
    I am getting this error when trying to load a subscene with netcode.

    This occurs after these steps, in order:
    1. Default subscene (subscene #0) is autoloaded on play
    2. Client adds NetworkStreamInGame, sends rpc to server
    3. Server adds NetworkStreamInGame
    4. Server loads subscene #1 from an EntitySubsceneReference attached to an entity in subscene #0
    5. Server sends a `new Subscene(entitySubsceneReference)` over rpc to client
    6. Server spawns some ghost prefabs *
    7. Client receives rpc and loads subscene #1 using `subscene.SceneGUID`
    8. Error occurs: `The ghost collection contains a ghost which does not have a valid prefab on the Client! Ghost:''.`

    * At first I thought there was something wrong with the asset ghost prefabs, but I found that if I removed all of the ghosts that are within subscene #1, then the error does not occur.

    Other notes:
    - I still get error after disabling ghost in scene, it only goes away if they are completely removed before playing
    - If subscene #1 is opened before I press play, no error occurs
    - I have netcode client target in project settings/entities/build set to "ClientAndServer"
    - The system that loads the subscene level waits for both client/server to have ghost sync

    I found these two threads with the same error but still not sure how to solve the issue:
    This section of the Unity netcode manual seems to help a bit: https://docs.unity3d.com/Packages/c...st-spawning.html#how-pre-spawned-ghosts-works but there's not enough information on prespawning to help me figure this out.

    Is there a standard procedure for dynamically loading/unloading subscenes with netcode? Or any in-depth knowledge on how prespawning works would help.
     
  2. Jonathan_L

    Jonathan_L

    Joined:
    Jan 26, 2016
    Posts:
    43
    I was able to sort of fix this by loading the scene on the client before the loading on the server. (Loading the scene at the same time should also work, but I don't think I can do that)

    I think I understand prespawning a bit better. If anybody is running into a similar issue, it's just as Tim says in the first thread link I shared. The server was loading the subscene before the client did (because of the time it takes for rpc) and then a mismatch in the ghost collection count caused the error. Server had more ghosts than the client, so the client got kicked out of the game.

    It would be nice if prespawning worked just like normal ghost spawning. If the server loads a subscene with prespawned ghosts inside, it should "Instantiate" the ghosts on all clients whether or not clients load that scene. The client could then load the scene at any time since it doesn't spawn ghosts anyway. Either this or maybe there could be a function to load a subscene without any prespawned ghosts and another one to get all ghost prefabs from a subscene.

    Could this be possible?
     
  3. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    892
    Prespawned ghosts, the way they work today, allow client to load the sub-scene with prespawn in any order and when they want.
    The client will load the instance from the scene, communicate to the server it loaded that prespawned-ghost section and the server will start streaming to the client the ghosts state from there.
    This is by design.

    Now, there is a caveats though in regard the prefabs: In this case, because the server also load a scene dynamically, the client need to inform the ghost collection system that is going to load the required resource using the Loading flag on the GhostCollectionPrefab list.

    Otherwise, the ghost collection will assume you didn't load the required data and trigger error.

    If you load for example a common sub-scene that contains only references to all the shared prefabs (but no ghost instance) on both server and client before setting the NetworkStreamInGame, then you can do that load-unload without doing any custom logic.

    In general, if you load sub-scene that contains prefabs references (and if they contains prespawned ghosts, they also contains prefab-reference if that prefab is not already referenced somewhere else) while the connection is already set to "in-game" require some manual written system by the user that mark the prefab resource as "LoadingActive" (every frame until the resource il loaded).

    Writing the full answer here will take bit now. I will post a full one shortly.
     
  4. Jonathan_L

    Jonathan_L

    Joined:
    Jan 26, 2016
    Posts:
    43
    I think doing this manual update might work for me. I saw you gave an example in the other post but I did not know the best way to implement it for my use-case.

    The server runs some logic to decide which subscene to load at some game state. Since the client doesn't know if a scene is about to load yet, it can't set prefab resources to "LoadingActive", unless it does this all of the time. So I'm thinking first the server sends an RPC to the client, saying it is about to load a particular scene. Then the client can start marking the prefab resources for that particular scene as "LoadingActive" until loading is complete.

    The problem with this is how would the client know which prefab resources belongs to which scene, so that it can mark those as active?

    Also, will the server still simulate the ghosts that are marked as "LoadingActive" by the client, while the client is waiting for the resource to load?