Cam
Cam9h ago

Better way to take ownership of Rigidbodies on start?

Hey, this has been a long required thing to do in Normcore, and truthfully I've always done it in kind of a hacky way where whenever anyone joins they take ownership of any unowned rigidbodies, but I would like it to really only be the first client joining to do this. Sadly there doesn't seem to immediately be any way to check if you are the "initializer". I know there is the model.isFreshModel however you cannot request ownership during this time, so I'm kinda curious overall if there's some better way. I'd definitely prefer to not have a bool per every single rigidbody of if it was initialized lol
5 Replies
kapa.ai
kapa.ai9h ago
Hi @Cam. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- There isn’t a built-in “initializer” flag in Normcore that directly tells you if you’re the first client in the room, nor is there a built-in event specifically for the first client to take ownership of all unowned rigidbodies. Your observation about isFreshModel is correct: while it indicates a newly created model, you cannot request ownership during that time. Recommended Approach: - Ownership on Instantiation: The most robust way is to assign ownership at the time of instantiation using Realtime.Instantiate() with ownedByClient: true. This ensures the instantiating client owns the object from the start, and you avoid race conditions or the need for post-hoc ownership assignment. For scene objects, you can use the “Owned by Creating Client” flag in the inspector for RealtimeViews that exist in the scene, but this only works for the client that creates the object, not for all scene objects on room join RealtimeView Advanced Settings. - Manual Assignment by First Client: If you need to assign ownership of existing scene rigidbodies only to the first client, you’ll need a way to determine if you are the first client. Normcore does not provide a direct API for “first client” detection. A common workaround is to have a designated “room manager” object that is instantiated with ownedByClient: true and persists for the session. The owner of this object can be considered the initializer, and only that client should run the logic to take ownership of unowned rigidbodies. - Avoiding Per-Rigidbody Bools: Instead of tracking a bool per rigidbody, centralize the logic: when the “initializer” client joins, iterate over all unowned rigidbodies and call RequestOwnership() on their RealtimeTransform components Requesting ownership of any RealtimeComponent. Example:
if (isRoomInitializer) {
foreach (var rt in FindObjectsOfType<RealtimeTransform>()) {
if (rt.isUnownedSelf) {
rt.RequestOwnership();
}
}
}
if (isRoomInitializer) {
foreach (var rt in FindObjectsOfType<RealtimeTransform>()) {
if (rt.isUnownedSelf) {
rt.RequestOwnership();
}
}
}
You’ll need to implement your own logic for isRoomInitializer, typically by checking if you own a special manager object. Summary:
There’s no built-in “first client” flag or event, but you can use a manager object to designate the initializer and have that client take ownership of unowned rigidbodies at startup. This avoids the need for per-rigidbody state and keeps your logic centralized. If you need more advanced room management, you may need to implement custom server-side logic, but for most use cases, the above pattern is sufficient Ownership + Lifetime Flags. If you need more details or code samples, let me know! ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai9h ago
<@271788139381653514> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Cam
CamOP9h ago
(I should probably specify this case is for scene objects, which of course are unowned and need to be taken over to simulate) The bots answer wouldn't really work
Mechabit
Mechabit8h ago
you'd only need one bool in the scene to say it has been initialised or do the thing if you are client 0 which would work most of the time you'd only ever not get a client 0 if someone started to join and then fails at the same time or client 0 joins and then leaves and the id gets reused and you initialise twice which probably wont be too bad or use lowest client id method if there's no client 0
maxweisel
maxweisel8h ago
this is a really interesting idea. we've got an AutoDistributeOwnership component in the works, but I like the idea of the person who created the model automatically requesting ownership I'll write that up

Did you find this page helpful?