Late Joiners Cannot see previous players
Hi, I connect to multiplayer. When connected, I load the scene. That scene spawns the player
Problem:
- For player1 (which is the first player), it can see player 2 when it joins late sync is fine.
- But for player2, the late joiner, in the unity hierarchy, there is no player1. It was not instantiated.
29 Replies
Hi @Pantoy. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
Your issue—where late joiners do not see previously spawned players—typically happens if player prefabs are instantiated locally on each client, rather than through Normcore’s networked instantiation system. In Normcore, to ensure all players (including late joiners) see the same set of avatars, you must use Realtime prefabs and instantiate them with
When a player joins, instantiate their avatar using: This ensures the player object is created in the Normcore datastore and is visible to all clients, including late joiners. If you use Unity’s
The player prefab must: - Be placed in a
If you instantiate the player in the scene (e.g., via a scene object or Unity’s
Make sure you’re not running into issues where the model isn’t initialized yet. For prefabs, all views and components are ready by the time
If player1 is not visible to player2 (the late joiner), it’s almost certainly because player1’s avatar was not instantiated using
Realtime.Instantiate(), not Unity’s standard Instantiate() method.
Here’s what you should check and do:
1. Use Realtime.Instantiate for Player PrefabsWhen a player joins, instantiate their avatar using: This ensures the player object is created in the Normcore datastore and is visible to all clients, including late joiners. If you use Unity’s
Instantiate(), the object will only exist locally and will not be synchronized across the network Guides > Creating a Player Controller.
2. Prefabs Must Be in Resources Folder and Have RealtimeViewThe player prefab must: - Be placed in a
Resources folder.
- Have a RealtimeView component on the root GameObject.
- Be instantiated only after the client has connected to the room (e.g., in the didConnectToRoom callback) Realtime API.
3. Scene Instantiation vs. Network InstantiationIf you instantiate the player in the scene (e.g., via a scene object or Unity’s
Instantiate()), it will not be synchronized. Only objects instantiated with Realtime.Instantiate() are tracked in the datastore and will be present for late joiners Realtime API.
4. Check for Ownership and Model InitializationMake sure you’re not running into issues where the model isn’t initialized yet. For prefabs, all views and components are ready by the time
Start() is called. For scene objects, wait for realtime.connected == true or the didConnectToRoom event [Support QA Part 2].
Summary:If player1 is not visible to player2 (the late joiner), it’s almost certainly because player1’s avatar was not instantiated using
Realtime.Instantiate(). Update your code to use Normcore’s instantiation method, and late joiners will see all previously spawned players.
If you’ve already done this and still have issues, double-check that your prefab setup matches the requirements above and that you’re not accidentally instantiating the player in a way that bypasses Normcore’s networking.
Let me know if you need help with a specific code snippet or setup!
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@620524702938562560> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@Normcore Assistant
Let me check the knowledge base for you again. One moment! :books:
Sorry @Pantoy, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist:
Perhaps try again in 15mins?
@Normcore Assistant
I am using the Normcore instantiation:
spawnedPlayer = MultiplayerManager.Instance.Instantiate(playerPrefab.name + " Realtime", spawnPosition + spawnOffset, Quaternion.identity,
ownedByClient: true,
preventOwnershipTakeover: true,
destroyWhenOwnerLeaves: true,
destroyWhenLastClientLeaves: true);
In MultiplayerManager
public GameObject Instantiate(string prefabName,
Vector3 position,
Quaternion rotation, bool ownedByClient, bool preventOwnershipTakeover, bool destroyWhenOwnerLeaves, bool destroyWhenLastClientLeaves)
{
return Realtime.Instantiate(prefabName, position, rotation, new Realtime.InstantiateOptions
{
ownedByClient = ownedByClient,
preventOwnershipTakeover = preventOwnershipTakeover,
destroyWhenOwnerLeaves = destroyWhenOwnerLeaves,
destroyWhenLastClientLeaves = destroyWhenLastClientLeaves,
useInstance = _realtime
});
}
Let me check the knowledge base for you again. One moment! :books:
----------------------
Based on your code, you are correctly using
- The prefab must be in a
- The instantiation should occur after the client has connected to the room, typically in the
- Ensure you are not also instantiating the player locally with Unity’s
The string passed to
Make sure all clients are connecting to the same room name and region. - Prefab Model Initialization:
If you are trying to access the model or ownership before the model is initialized, it may not be ready. For prefabs, models are ready by
The flags
Realtime.Instantiate() with the appropriate options for ownership and lifetime flags. This should ensure that player prefabs are instantiated in a way that is synchronized across all clients, including late joiners, as long as the following requirements are met:
1. Prefab Setup:- The prefab must be in a
Resources folder.
- The root of the prefab must have a RealtimeView component.
- All RealtimeComponent scripts (such as RealtimeTransform) must be attached to the prefab and visible in the RealtimeView's component list in the inspector Realtime API, RealtimeView.
2. Instantiation Timing:- The instantiation should occur after the client has connected to the room, typically in the
didConnectToRoom callback. Instantiating before the connection is established can result in the object not being synchronized Guides > Creating a Player Controller.
3. No Local Instantiation:- Ensure you are not also instantiating the player locally with Unity’s
Instantiate() anywhere else in your code, as this would create a local-only object that is not synchronized [Support QA Part 2].
If all of the above are true and you are still experiencing the issue where late joiners do not see existing players, here are some additional things to check:
- Prefab Name Consistency:The string passed to
Realtime.Instantiate() must exactly match the prefab name in the Resources folder (case-sensitive, no extra spaces).
- Room Connection:Make sure all clients are connecting to the same room name and region. - Prefab Model Initialization:
If you are trying to access the model or ownership before the model is initialized, it may not be ready. For prefabs, models are ready by
Start(), but for scene objects, wait for realtime.connected == true or the didConnectToRoom event [Support QA Part 2].
- Destroy Flags:The flags
destroyWhenOwnerLeaves and destroyWhenLastClientLeaves are correct for cleaning up player objects when clients disconnect, but they do not affect late joiner visibility as long as the owner is still in the room Destroy a prefab when a client disconnects.
If all of these are correct and the issue persists, the knowledge sources do not provide further troubleshooting steps for this specific scenario. In that case, you may want to check for:
- Errors or warnings in the Unity console related to Normcore.
- Whether the player prefab is being destroyed or not instantiated due to logic elsewhere in your code.
If you can confirm all the above and still have the issue, consider reaching out to the Normcore community for more targeted support.
Let me know if you need help verifying any of these steps or want to share more details about your prefab setup!
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@620524702938562560> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@Normcore Assistant I am pretty sure they are in the same room.. Since I have networked projectiles also.. and they are firing from both players. The issues is just player1 was not instantiated in player2 perspective.
Let me check the knowledge base for you again. One moment! :books:
----------------------
Given your setup—where projectiles are networked and visible to both players, but player1 is not instantiated for player2 (the late joiner)—this suggests that your networking is generally working, but there is a specific issue with the player prefab instantiation or its lifetime settings.
Based on the knowledge sources, here are the most likely causes and checks:
1. Prefab Lifetime Flags
If you use
The prefab must be in a
The player prefab should be instantiated only after the client has connected to the room, typically in the
If the player prefab is also present in the scene (not instantiated via
RealtimeComponents cannot be added at runtime; they must be present on the prefab and registered in the inspector. If the prefab is missing required components, it may not synchronize correctly Realtime > Common Questions. Summary:
If projectiles are working but player avatars are not, the most likely issue is with the player prefab setup or the timing of instantiation. Double-check the prefab’s location, naming, and that it is only instantiated after connecting to the room using
If you use
destroyWhenOwnerLeaves: true and destroyWhenLastClientLeaves: true, the player object will be destroyed when the owner disconnects or when the last client leaves the room. However, as long as player1 is still in the room, their player object should persist and be visible to late joiners. If the object is not visible, it suggests it may not have been properly registered in the datastore, or there is an issue with the prefab setup or instantiation timing Room > Ownership + Lifetime Flags.
2. Prefab SetupThe prefab must be in a
Resources folder and have a RealtimeView on the root. If the prefab is not set up correctly, it may not synchronize across clients. Double-check that the prefab name passed to Realtime.Instantiate() matches exactly (including case and spaces) the prefab in the Resources folder Realtime API.
3. Instantiation TimingThe player prefab should be instantiated only after the client has connected to the room, typically in the
didConnectToRoom callback. Instantiating before the connection is established can result in the object not being synchronized and not appearing for late joiners Guides > Creating a Player Controller.
4. No Scene InstantiationIf the player prefab is also present in the scene (not instantiated via
Realtime.Instantiate()), it will not be synchronized. Only objects instantiated with Realtime.Instantiate() are tracked in the datastore and visible to late joiners Realtime API.
5. RealtimeComponent LimitationsRealtimeComponents cannot be added at runtime; they must be present on the prefab and registered in the inspector. If the prefab is missing required components, it may not synchronize correctly Realtime > Common Questions. Summary:
If projectiles are working but player avatars are not, the most likely issue is with the player prefab setup or the timing of instantiation. Double-check the prefab’s location, naming, and that it is only instantiated after connecting to the room using
Realtime.Instantiate(). If all of these are correct and the issue persists, the knowledge sources do not provide further troubleshooting steps for this specific scenario.
If you need to debug further, you might want to log when and where the player prefab is instantiated and confirm that it is not being destroyed or skipped due to logic elsewhere in your code.
If you have verified all of the above and the problem remains, the knowledge sources do not contain enough information to provide a definitive answer for your specific case.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@620524702938562560> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@Normcore Assistant is it maybe because I load a scene after I connect?
Let me check the knowledge base for you again. One moment! :books:
----------------------
Yes, loading a new scene immediately after connecting to the room can cause the issue you’re seeing.
Here’s why:
When you call
- Move your player instantiation code to run after the new scene has finished loading (e.g., in a
Yes, loading a scene right after connecting can prevent player instantiation for late joiners if the instantiation does not occur after the new scene is loaded. Make sure to instantiate your player prefab in the new scene, after it has loaded, to ensure proper synchronization for all clients. If you need more details on how to structure this, let me know! ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
When you call
SceneManager.LoadScene() in your DidConnectToRoom callback, Unity unloads the current scene and loads the new one. If your player instantiation logic (using Realtime.Instantiate()) is not triggered after the new scene is loaded, or if the MultiplayerManager (and its Realtime instance) is not present in the new scene (or not marked as DontDestroyOnLoad), then the player prefab will not be instantiated or registered in the datastore for late joiners.
Key points from the knowledge sources:
- Realtime prefabs must be instantiated after the client has connected to the room, and the instantiation should happen in the active scene where you want the player to appear Guides > Creating a Player Controller.
- If you load a new scene, you need to ensure that your instantiation logic runs after the new scene is loaded, not before. Otherwise, the player object may not be created in the correct scene context, or at all.
What to do:- Move your player instantiation code to run after the new scene has finished loading (e.g., in a
Start() or OnSceneLoaded callback in the new scene).
- Make sure your MultiplayerManager and Realtime instance persist across scenes (using DontDestroyOnLoad as you have done).
Summary:Yes, loading a scene right after connecting can prevent player instantiation for late joiners if the instantiation does not occur after the new scene is loaded. Make sure to instantiate your player prefab in the new scene, after it has loaded, to ensure proper synchronization for all clients. If you need more details on how to structure this, let me know! ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
<@620524702938562560> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@Normcore Assistant I think i did everything you told me. But still facing the issue
Let me check the knowledge base for you again. One moment! :books:
----------------------
Based on the information in the knowledge sources, if you are still facing the issue where late joiners do not see previously spawned players—even after following the recommended setup (using
Realtime.Instantiate(), correct prefab setup, and instantiating after connecting to the room)—then the knowledge sources do not provide a definitive solution for your specific scenario.
The documentation emphasizes that:
- Prefabs must be instantiated with Realtime.Instantiate() after connecting to the room, and must be in a Resources folder with a RealtimeView on the root Realtime API.
- Instantiation should occur after the scene is loaded and after the connection is established Guides > Creating a Player Controller.
- Lifetime flags like destroyWhenOwnerLeaves and destroyWhenLastClientLeaves should not prevent late joiners from seeing existing players as long as the owner is still in the room Room > Ownership + Lifetime Flags.
If all of these are correct and you are still experiencing the issue, the knowledge sources do not contain enough information to provide a confident answer or further troubleshooting steps for your specific case.
You may want to:
- Double-check for any errors or warnings in the Unity console related to Normcore.
- Ensure that the player prefab is not being destroyed or skipped due to other logic.
- Consider reaching out to the Normcore community or support for more targeted assistance.
I'm sorry, but there's no additional information in the provided knowledge sources to resolve your issue further.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@620524702938562560> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@Normcore Assistant I understand now, in my lobby scene when I connect, it spawns the previous player and gets destroyed in the game scene. that was the problem
Let me check the knowledge base for you again. One moment! :books:
----------------------
Yes, your analysis matches the expected behavior described in the knowledge sources. If you instantiate the player prefab in the lobby scene and then load a new game scene, the instantiated player object from the lobby will be destroyed unless it is marked as
DontDestroyOnLoad. This means late joiners will not see the previous players, because their player objects no longer exist in the new scene.
To ensure all players are visible to late joiners, you should instantiate the player prefab in the game scene after it has loaded and after connecting to the room. This way, the player objects are present in the correct scene and are properly synchronized for all clients, including late joiners. This approach aligns with the recommended workflow in the Normcore documentation, which states that instantiation should occur after connecting to the room and in the active scene where you want the player to appear Guides > Creating a Player Controller.
If you need to persist objects across scenes, you can use DontDestroyOnLoad, but for most multiplayer scenarios, instantiating in the correct scene after loading is the best practice.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@620524702938562560> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@Normcore Assistant it automatically instantiates the previous player during connection. is there any option for this to manually recover instead of automatically?
Let me check the knowledge base for you again. One moment! :books:
----------------------
I'm sorry, but the knowledge sources do not mention any option to manually recover or instantiate previous players instead of having Normcore automatically instantiate them when connecting to a room. According to the documentation, Normcore's datastore and prefab instantiation system are designed to automatically synchronize and instantiate persistent objects (including player prefabs) for all clients, including late joiners, to ensure consistency across the network. There is no documented setting or API to override this behavior and require manual recovery of previous players or persistent objects upon connection Room > Datastore, Guides > Creating a Player Controller.
If you need more granular control over object instantiation or recovery, the knowledge sources do not provide guidance on how to achieve this within the standard Normcore workflow.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
<@620524702938562560> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
are you able to create a blank unity project that repros this issue?
this is probably a test case we’ve tested more than anything else. if there’s a bug here I’d love to pass it onto our team
do you see any errors in your console on the client that can’t see all players?
anything about missing prefabs?
@Max yup i tried a minimal scene... when player2 joins, it instantiates player1 in the lobby scene where my logic for joining room is implemented. so switching scenes will destroy those. I just wish like we can control when we can instatiate previous players instead of instantiating directly when we are connected to room
It looks like you aren't using load scene additive so everything in the previous scene is destroyed including the Realtime and any avatars. Unless you called DontDestroyOnLoad on them
@Pantoy what would your ideal setup look like here?
already used one scene for our project... the plan before was joining room will be in lobbyscene.. once connected, load the gamescene.
that should work fine. I guess I don’t understand the problem. if you unload your lobby it makes sense you’d disconnect from that room and connect to the game scene room, which would destroy and recreate your avatars. in theory, you can create one Realtime instance that persists and you can mark your avatars to [DoNotDestroyOnLoad], but then all players will be connected to the exact same room all of the time.
lets see your avatar prefab