Hey all! I wanted to share a small tip that I came up with, to cope with what is I think a common use case. I will call it “synced folder objects”.
Sometimes, you might have a scene with a bunch of synced Prefab instances that are parented to another non-synced GameObject. Basically you are using this object as a folder.
Say for instance, a bunch of Coin Prefab instances parented to a Collectables GameObject, just to keep the hierarchy tidy. Like this:
- Collectables - 🔹Coin - 🔹Coin
(where is a synced object, with CoherenceSync on it)
When entering the game everything is fine and dandy on all Clients. Even if you lose authority over those objects because someone else has it, coherence won’t move them.
What might happen is that a logic script spawns a new collectable, and naturally it parents it to the Collectables object to keep the scene tidy, like before. This all works on the side spawning the object, but…
… when this object is being instantiated remotely, it won’t be automatically parented to the Environment object. Not knowing where to put it, coherence will just instantiate it on the root. So now your hierarchy root might be polluted with a ton of objects at runtime, making it harder to debug.
- Collectables - 🔹Coin - 🔹Coin - 🔹[remote]Coin - 🔹[remote]Heart
You could also send a NetworkCommand and ask the newly created object to be parented, but it’s wonky and could just lead to bugs later on.
So why not make the organiser object(s) synced too? You can define a new, empty synced Prefab (basically an empty object with just Transform and CoherenceSync), set it to be persistent, and give it a unique ID.
When a spawner script creates a new collectable and parents it on the authority side, coherence will also parent it on non-authoritative Clients, because it can recreate the parenting structure between synced objects. So the hierarchy on other clients will look like this:
- 🔹Collectables - 🔹Coin - 🔹Coin - 🔹[remote]Coin - 🔹[remote]Heart
In my opinion, using this technique for 5-10-20 objects has a negligible cost on performance. And because folder objects are not moving nor they get destroyed, there is basically no update during gameplay, so again, no per-frame costs.
Things to watch out for
This is not for all game genres! If the logic of an object changes whether they are on the root or not (for instance, having a parent means something), then you can’t do this.
Also, there might be a case where a player is not seeing these collectables because the container object falls out of a LiveQuery. This is the case because coherence uses the topmost parent to determine if an object is in a LiveQuery or not. If spatial queries are important to your game, you might want to not use this trick.