ixikos
ixikos2mo ago

Do I need ownership to modify a value on a RealtimeComponent?

Do I need ownership to modify a value on a RealtimeComponent?
9 Replies
kapa.ai
kapa.ai2mo ago
Hi @ixikos. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Yes, you do need ownership to modify a value on a RealtimeComponent. In Normcore, the ownership settings of a parent are enforced on all children. If a model is owned by one client, all other clients are blocked from making changes to the model or any of its child models. This includes RealtimeComponents as they use models. For example, if a RealtimeView is owned by the local player, only the local player will be able to make changes to the RealtimeComponents associated with it. To modify a value on a RealtimeComponent, you need to request ownership of it. You can do this by calling the RequestOwnership() method on the RealtimeComponent. Here's an example of how to request ownership of a RealtimeTransform, which is a RealtimeComponent subclass:
public void CreateObjectAndRequestOwnershipOfRealtimeTransform() {
// Instantiate the My Object prefab, leave the view unowned.
GameObject myObject = Realtime.Instantiate("My Object", ownedByClient: false);

// Get the RealtimeTransform component
RealtimeTransform realtimeTransform = myObject.GetComponent<RealtimeTransform>();

// Request Ownership
realtimeTransform.RequestOwnership();
}
public void CreateObjectAndRequestOwnershipOfRealtimeTransform() {
// Instantiate the My Object prefab, leave the view unowned.
GameObject myObject = Realtime.Instantiate("My Object", ownedByClient: false);

// Get the RealtimeTransform component
RealtimeTransform realtimeTransform = myObject.GetComponent<RealtimeTransform>();

// Request Ownership
realtimeTransform.RequestOwnership();
}
Please note that the RequestOwnership() call is only rejected if the RealtimeView or a parent RealtimeView is owned by a different client. For more information, you can refer to the Normcore Documentation (https://normcore.io/documentation/room/ownership-and-lifetime-flags#how-ownership-is-enforced). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@346532823143809046> kapa.ai is still learning and improving, please let us know how it did by reacting below
ixikos
ixikos2mo ago
@Normcore Assistant so if I want to modify the health on a target, then someone else modify that, would we each need to RequestOwnership prior to modifying that health value? What happens if we both try to at the same time
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- In Normcore, if you want to modify a shared value like a player's health, it's recommended to use a RealtimeDictionary or a StringKeyDictionary instead of a RealtimeComponent on the avatar. This is because the avatar's RealtimeView is owned by the local client, and only the local client can modify it. If you try to clear ownership of the avatar, you may run into issues. If you use a RealtimeDictionary or a StringKeyDictionary, you can avoid the need for ownership requests when modifying shared values. These data structures allow multiple clients to modify values without needing to request ownership. However, if you are using a RealtimeComponent and two clients try to request ownership at the same time, the server will decide who gets ownership. The client that doesn't get ownership will have its changes rolled back. Here's an example of how you might handle this situation:
// Get the RealtimeView component
RealtimeView myObjectView = myObject.GetComponent<RealtimeView>();

// Check if the RealtimeView is owned locally
if (myObjectView.isOwnedLocally) {
// If it is, modify the health value and destroy the object
// ModifyHealth() is a hypothetical method you would need to implement
ModifyHealth(myObject);
Realtime.Destroy(myObject);
} else {
// If it isn't, request ownership
myObjectView.RequestOwnership();
}
// Get the RealtimeView component
RealtimeView myObjectView = myObject.GetComponent<RealtimeView>();

// Check if the RealtimeView is owned locally
if (myObjectView.isOwnedLocally) {
// If it is, modify the health value and destroy the object
// ModifyHealth() is a hypothetical method you would need to implement
ModifyHealth(myObject);
Realtime.Destroy(myObject);
} else {
// If it isn't, request ownership
myObjectView.RequestOwnership();
}
For more information, you can refer to the Normcore Documentation (https://normcore.io/documentation/realtime/common-questions#im-trying-to-store-my-players-health-in-a-realtimecomponent-on-my-avatar-how-can-i-let-other-players-modify-this-values-or-others). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@346532823143809046> kapa.ai is still learning and improving, please let us know how it did by reacting below
Camobiwon
Camobiwon2mo ago
I don't believe this is true, I am pretty sure you can modify the values of components if they are unowned, as long as the RealtimeView isn't owned or locked
ixikos
ixikos2mo ago
cool , thanks, going to give that a try
maxweisel
maxweisel2mo ago
@Camobiwon is correct but make sure parent views are also unowned
ixikos
ixikos2mo ago
ya, worked like a charm - thanks