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
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
When a player grabs an item, you must call
When an item is released, ownership may need to be cleared (using
When using pooling, ensure that the
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
Do not request ownership on the parent
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
If the parent is owned, it can block ownership changes on the child
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 GrabWhen 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 OwnershipWhen 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 InstantiationWhen 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 ChangesIf 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
Example: Clearing Ownership on Release
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:
----------------------<@746506971334836224> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
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
don't clear ownership of the RT also click the box on the xr grab interactable that says add gravity on detach