Voltaia
Voltaia5mo ago

Are Realtime Views instantiated on a separate thread?

I'm experiencing some peculiar behavior. I have some networked game objects using a custom model. When they are instantiated, they add themselves to a static "instances" list on awake. In another game object, I am enumerating through that list in update. The issue is that when I instantiate them over the network, the enumeration fails. Collection was modified; enumeration may not execute. So, I may have a misunderstanding of what's happening, but my assumption is that Realtime.Instantiate happens on its own thread. How should I navigate this issue?
5 Replies
kapa.ai
kapa.ai5mo ago
Hi @Voltaia. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- The issue you're experiencing seems to be related to modifying a collection while iterating over it, which is not allowed in C#. This is a common issue in multithreaded programming, but it's not specifically related to Realtime.Instantiate() or Normcore's Realtime Views. In Normcore, Realtime.Instantiate() does not happen on its own thread. It instantiates a realtime prefab in the scene on all clients. The fully instantiated game object, all RealtimeViews and RealtimeComponents, along with their models will be initialized and ready for use immediately source (https://normcore.io/documentation/reference/classes/Normal.Realtime.Realtime). The error message you're seeing, Collection was modified; enumeration operation may not execute, is a common error in C# when a collection is modified while it's being iterated over. This can happen if you're adding or removing items from the collection in one part of your code while another part of your code is in the middle of a foreach loop over that collection. To resolve this issue, you could consider using a separate collection for adding new instances, and then merge this with your main collection when you're not iterating over it. Alternatively, you could use a collection type that is designed to be safe for concurrent modifications, such as one of the collections in the System.Collections.Concurrent namespace. Here's an example of how you might handle this with a separate collection:
// This is your main collection
List<MyObject> instances = new List<MyObject>();

// This is where you add new instances
List<MyObject> newInstances = new List<MyObject>();

void Update() {
// Merge new instances with the main collection
instances.AddRange(newInstances);
newInstances.Clear();
// Now it's safe to iterate over instances
foreach (var instance in instances) {
// Do something with instance
}
}

void Awake() {
// Add this instance to the new instances collection
newInstances.Add(this);
}
// This is your main collection
List<MyObject> instances = new List<MyObject>();

// This is where you add new instances
List<MyObject> newInstances = new List<MyObject>();

void Update() {
// Merge new instances with the main collection
instances.AddRange(newInstances);
newInstances.Clear();
// Now it's safe to iterate over instances
foreach (var instance in instances) {
// Do something with instance
}
}

void Awake() {
// Add this instance to the new instances collection
newInstances.Add(this);
}
Remember, this is just a general C# solution and may need to be adapted to fit your specific use case. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai5mo ago
<@276154194606424064> kapa.ai is still learning and improving, please let us know how it did by reacting below
maxweisel
maxweisel5mo ago
Normcore does not thread anything in Unity. Afaik none of the Unity APIs are thread safe, including prefab instantiation. As the bot mentioned, this error is usually unrelated to a thread, and more often due to modifying a collection from within a loop that's iterating over the contents. My guess is that the bug is unrelated to Normcore and more related to the collection being empty on local clients (so the iteration loop does nothing) and it being non-empty on remote clients
Voltaia
VoltaiaOP5mo ago
It's peculiar because I'm not modifying the collection within an iterating loop. It's only modified when objects are instantiated and destroyed to add and remove from the static instances list. Ah. Found the issue. Thanks for the help 🫡
Reputation Bot
Reputation Bot5mo ago
Thank confirmation
Thank you for giving someone Reputation. You can give 0 more reputation.
This message will selfdestruct in 1 minute.