Ryan Green
Ryan Green3mo ago

Is there a way to change ownership automatically when remote rigidbody is owned by another client?

I want ownership to change when an rigidbody owned by client a hits a rigidbody owned by client b. The object rigidbody by client b is automatically moving, not asleep. What is the best way to approach this?
6 Replies
kapa.ai
kapa.ai3mo ago
Hi @Ryan Green | MONA. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Yes, there is a way to change ownership automatically when a Rigidbody owned by one client interacts with a Rigidbody owned by another client. This is handled by the RealtimeTransform component in NormalVR. When a Rigidbody with a RealtimeTransform component collides with another Rigidbody with a RealtimeTransform component, it will automatically call RequestOwnership() on the second object, as long as the second object is not already owned by another client. This ensures that the same client can simulate both objects in the collision, preventing the appearance of delays during the objects' interactions. Here is an example of how this works:
// Let's say you're holding a ball that has a Rigidbody and RealtimeTransform component on it.
Rigidbody ballRigidbody = ball.GetComponent<Rigidbody>();
RealtimeTransform ballRealtimeTransform = ball.GetComponent<RealtimeTransform>();

// If you throw it, RealtimeTransform will automatically call RequestOwnership() when it collides with another object,
// as long as the other object has a Rigidbody and RealtimeTransform component on it, and it is not owned by anyone already.
Rigidbody otherRigidbody = otherObject.GetComponent<Rigidbody>();
RealtimeTransform otherRealtimeTransform = otherObject.GetComponent<RealtimeTransform>();

if (otherRigidbody != null && otherRealtimeTransform != null && !otherRealtimeTransform.isOwned)
{
ballRealtimeTransform.RequestOwnership();
}
// Let's say you're holding a ball that has a Rigidbody and RealtimeTransform component on it.
Rigidbody ballRigidbody = ball.GetComponent<Rigidbody>();
RealtimeTransform ballRealtimeTransform = ball.GetComponent<RealtimeTransform>();

// If you throw it, RealtimeTransform will automatically call RequestOwnership() when it collides with another object,
// as long as the other object has a Rigidbody and RealtimeTransform component on it, and it is not owned by anyone already.
Rigidbody otherRigidbody = otherObject.GetComponent<Rigidbody>();
RealtimeTransform otherRealtimeTransform = otherObject.GetComponent<RealtimeTransform>();

if (otherRigidbody != null && otherRealtimeTransform != null && !otherRealtimeTransform.isOwned)
{
ballRealtimeTransform.RequestOwnership();
}
This will ensure that the collision works smoothly for local and remote players. However, please note that RealtimeTransform will automatically call ClearOwnership() when the Rigidbody comes to rest in order to allow other clients to take it over and simulate it. If you want to maintain ownership while the Rigidbody is sleeping, you can set Maintain Ownership While Sleeping in the Unity editor[^1^][^2^]. ^1^]: [RealtimeTransform + Physics (https://normcore.io/documentation/realtime/networked-physics#realtimetransform--physics) ^2^]: [Rigidbody mode (https://normcore.io/documentation/realtime/realtimetransform#rigidbody-mode) ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@337874773742845953> kapa.ai is still learning and improving, please let us know how it did by reacting below
Ryan Green
Ryan Green3mo ago
@Normcore Assistant can I override this default behavior so that if the second object is already owned by another client, request ownership still occurs on collision
kapa.ai
kapa.ai3mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- The default behavior of the RealtimeTransform component in NormalVR is designed to respect the ownership of objects. If an object is already owned by a client, the RequestOwnership() method will not take effect on collision[^1^]. This is to prevent conflicts and ensure smooth and predictable behavior in a multiplayer environment. However, if you want to override this behavior, you would need to implement your own custom logic. This could involve checking the ownership status of the object upon collision and then attempting to request ownership regardless of its current status. Please note that even if you call RequestOwnership(), the server may still deny the request if the preventOwnershipTakeover flag is set to true or if the object's parent is owned by another client[^2^]. It's important to carefully consider the implications of overriding the default ownership behavior, as it could lead to unexpected results or conflicts between clients. ^1^]: [RealtimeTransform + Physics (https://normcore.io/documentation/realtime/networked-physics#realtimetransform--physics) ^2^]: [RequestOwnership() + ClearOwnership() (https://normcore.io/documentation/room/ownership-and-lifetime-flags#requestownership--clearownership) ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
Mechabit
Mechabit3mo ago
just use oncollisionenter to request ownership
maxweisel
maxweisel3mo ago
yeah you’ll just call RequestOwnership, but you’ll want to make sure the script doesn’t also make Client B take over ownership of Client A’s rigidbody ie if you’re hitting a baseball with a bat, you’ll want to make sure the bat checks that it’s only ever taking over ownership of a baseball