Armand
Armand10h ago

I am having trouble with item based ownership

In our game, we have items that mainly driven via XRGrabInteractable.cs and RealtimeTransform.cs and can be held by the player. It works 90% the way I want it too, but, I have edges case where items that are instantiated can sometimes become 'suspended' in air. These items are spawned via real-time instantiation and utilize real-time pooling. This item 'suspended' in air bug can also be triggered if players are rapidly passing items back and forth to each other, which leads me to believe it is an ownership issue. When the bug occurs, the player who owns the realtime can grab the item and move it around normally. When they let go of it, the item stays either static in air, or floats towards the direction of the release. On the clients who do not own the item in that moment, the item doesn't move at all.
4 Replies
kapa.ai
kapa.ai10h ago
Hi @Armand. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Your description strongly suggests an ownership synchronization issue with your items, especially during rapid handoffs or after instantiation. Here are the most relevant points and recommendations based on the Normcore documentation: Key Points from Normcore Docs 1. Ownership is Required for Movement
Only the client that owns a RealtimeTransform can move it. If another client tries to move it without ownership, the object will snap back or appear static on other clients. This matches your observation that only the owner can move the item, and others see it frozen or not moving at all [RealtimeTransform]. 2. RequestOwnership() on Grab
When a player grabs an item, you must call RequestOwnership() on the RealtimeTransform to ensure that client becomes the authoritative source for its position and movement. If this is not done reliably (e.g., due to race conditions during rapid handoffs), the item may become "suspended" or desynced [Ownership + Lifetime Flags]. 3. Clearing Ownership
When an item is released, ownership may need to be cleared (using ClearOwnership()) so that the next client can take over. However, if you clear ownership too quickly (e.g., immediately after moving), Normcore may not have time to sync the last state, resulting in the item appearing stuck or floating [Common Questions]. 4. Pooling and Instantiation
When using pooling, ensure that the RealtimeView and RealtimeTransform components are properly reset and that ownership is cleared or reassigned as needed when an item is reused. Otherwise, stale ownership data can persist, causing the item to be "owned" by a client that is no longer interacting with it [RealtimeView Advanced Settings]. 5. Rapid Ownership Changes
If multiple clients are rapidly requesting ownership, or if ownership is not properly cleared, you can end up in a state where no one owns the object, or the wrong client does. This is especially problematic if the parent RealtimeView is owned, as it can block ownership changes on child components [Ownership + Lifetime Flags]. Recommendations - Always call RequestOwnership() on the RealtimeTransform when a player grabs an item.
Do not request ownership on the parent RealtimeView unless you want to block others from taking ownership of the transform [Common Questions]. - Avoid calling ClearOwnership() immediately after releasing or moving the item.
Let Normcore synchronize the last state before clearing ownership. If you clear ownership too quickly, the state may not be sent to the server [Common Questions]. - On item release, consider leaving the item unowned (ownerID = -1), so the next client can take ownership when they grab it. - When pooling, ensure you reset ownership and state on the pooled object before reusing it. - Debug ownership state by logging the ownerID of the RealtimeTransform on grab/release and when the bug occurs. This can help you confirm if the item is truly unowned or owned by the wrong client. - Check for parent RealtimeView ownership.
If the parent is owned, it can block ownership changes on the child RealtimeTransform [Ownership + Lifetime Flags]. Example: Requesting Ownership on Grab
// On grab
realtimeTransform.RequestOwnership();
// On grab
realtimeTransform.RequestOwnership();
Example: Clearing Ownership on Release
// On release, optionally clear ownership
realtimeTransform.ClearOwnership();
// On release, optionally clear ownership
realtimeTransform.ClearOwnership();
But do not call ClearOwnership() immediately after moving the object; let Normcore sync the state first. --- If you follow these guidelines and still see issues, double-check your pooling logic and ensure that all ownership and state are reset when reusing objects. If the problem persists, consider adding debug logs for ownership transitions to pinpoint where the desync occurs. For more details, see the RealtimeTransform documentation and Ownership + Lifetime Flags. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai10h ago
<@746506971334836224> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
maxweisel
maxweisel9h ago
It sounds like you're requesting ownership of the view and the transform and then potentially only releasing one of them and so your view ownership is blocking other clients from taking over the transform ideally only request ownership of the RealtimeTransform and leave the view unowned
Mechabit
Mechabit9h ago
don't clear ownership of the RT also click the box on the xr grab interactable that says add gravity on detach

Did you find this page helpful?