rogan2528
rogan25284d ago

isOwnedLocallySelf seems to be incorrect for me

Sorry, I'm a newbie. I'm instantiating my prefab with: Realtime.InstantiateOptions options = new Realtime.InstantiateOptions(); options.destroyWhenLastClientLeaves = true; options.destroyWhenOwnerLeaves = true; options.ownedByClient = true; options.preventOwnershipTakeover = true; GameObject myPeerGO = Realtime.Instantiate("peer", options); RealtimeView realtimeView = myPeerGO.GetComponent<RealtimeView>(); realtimeView.RequestOwnershipOfSelfAndChildren(); However, on a change callback, on a property of that RealtimeComponent when I query: this.isOwnedLocallySelf, it returns as false. I'm not sure why it would be false. (And the remote ones are returning as true).
10 Replies
kapa.ai
kapa.ai4d ago
Hi @rogan2528. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- The behavior you're seeing—where isOwnedLocallySelf is false on your local instance, but true on remote ones—suggests that ownership is not being set as expected on your local client. Here are some key points and possible reasons based on the knowledge sources: 1. Ownership is set via Instantiate Options
When you use Realtime.Instantiate() with ownedByClient: true, the root RealtimeView of the prefab should be owned by the local client immediately after instantiation. This means isOwnedLocallySelf should return true for the local client on that view, unless something is interfering with the ownership assignment or the check is happening too early in the object lifecycle.
See: Requesting ownership of a RealtimeView 2. Timing of Ownership Checks
If you are checking isOwnedLocallySelf in Awake() or before the model is fully initialized, it may not be set yet. For prefabs, all views and components are initialized with their models and are ready to work with by the time Start() is called. If you check ownership before Start(), the value may be incorrect.
See: Why do I get the error “This view doesn't have a model yet...” 3. Redundant Ownership Requests
Calling RequestOwnershipOfSelfAndChildren() immediately after instantiation is not necessary if you already set ownedByClient: true in the instantiate options. The ownership should already be set, and calling this method again should not change the result, but it also shouldn't hurt. 4. Remote Ownership Appearing as Local
If remote clients are reporting isOwnedLocallySelf as true, this suggests a possible confusion between which client is considered "local" in each context. Remember, isOwnedLocallySelf is true only for the client that owns the object—so on each client, it will be true for objects they own, and false otherwise. Recommendations: - Ensure you are checking isOwnedLocallySelf after the model is initialized, ideally in Start() or in a callback like OnRealtimeModelReplaced(). - Double-check that your prefab is not being instantiated with Unity's Instantiate() by mistake, as this will break model/ownership synchronization. - Make sure you are not confusing the local/remote context when debugging across multiple clients. If you follow these guidelines and still see the issue, there may be a deeper problem with how the prefab or its components are set up. In that case, reviewing the prefab's RealtimeView and RealtimeComponent setup in the Unity editor for any misconfigurations is recommended. If you need to debug further, you can use the RealtimeView inspector at runtime to see ownership status and use the "Request Ownership" button to test ownership changes manually
See: RealtimeView Advanced Settings. If the problem persists, please provide more details about where and when you are checking isOwnedLocallySelf, and how you are testing across clients. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4d ago
<@214044513256210432> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
maxweisel
maxweisel4d ago
it sounds like you’re calling RequestOwnershipOfSelfAndChildren on all clients and so the local client owns it briefly but then remote clients also request it and take over which leads me to believe you’re calling it in Start() in a component on the prefab potentially in theory preventOwnershipTakeover should stop that though, so I’m not 100% sure
rogan2528
rogan2528OP4d ago
In this case, the RequestOwnershipOfSelfAndChildren is only being called when the local prefab is instantiated, so will only be on the local client. The "didChange" functions wouldn't be called before the ownership is set, correct? @kapa.ai When OnRealtimeModelReplaced is called, isOwnedLocallySelf is false, but isOwnedLocallyInHierarchy is true. Why would that be?
kapa.ai
kapa.ai4d ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- When OnRealtimeModelReplaced is called, it is possible for isOwnedLocallySelf to be false while isOwnedLocallyInHierarchy is true. This means that the specific component or model you are checking is not directly owned by the local client (isOwnedLocallySelf == false), but one of its parent views or models in the hierarchy is owned by the local client (isOwnedLocallyInHierarchy == true). This can happen because ownership in Normcore is hierarchical: if a parent RealtimeView or model is owned by the local client, all its children are protected by that ownership, but the children themselves may not have their own ownership set. In other words, the root or a parent in the hierarchy is the owner, and the child inherits the protection, but does not itself have the owner flag set. From the documentation:
Models can have other models as children, and 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.
>
...The RealtimeView's model contains the models for all child RealtimeViews and all RealtimeComponents, so any ownership settings on the RealtimeView apply to child views and to components as well.
>
...we can set ownership of the root RealtimeView, and the server will block all other clients from making modifications to any RealtimeView or RealtimeComponent model.
>
Source: Server Authority + Ownership + Lifetime Flags
So, in your case, the parent (likely the root RealtimeView of your prefab) is owned by the local client, but the specific component or model you are checking does not have its own ownership set, resulting in the observed values. This is expected behavior in Normcore's ownership model. If you need the child to be directly owned, you would need to explicitly set ownership on that child component or model. Otherwise, it will inherit the ownership protection from its parent, which is what isOwnedLocallyInHierarchy reflects. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4d ago
<@214044513256210432> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
rogan2528
rogan2528OP4d ago
Interesting. "OnRealTimeModelReplaced" is called before the "RequestOwnershipOfSelfAndChildren" line is even reached @kapa.ai Can you explain this error "RequestOwnership called on a model without a meta-model. Use [RealtimeModel(createMetaModel: true)] on your custom model to enable ownership."
kapa.ai
kapa.ai4d ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- This error means that you are calling RequestOwnership() on a custom RealtimeModel that was not compiled with a "meta-model." In Normcore, a meta-model is required for ownership and lifetime flags to work. Without it, the server cannot track or enforce ownership for that model. To fix this, you need to add the createMetaModel: true flag to your RealtimeModel attribute when defining your custom model. For example:
[RealtimeModel(createMetaModel: true)]
public partial class MyModel {
[RealtimeProperty(1, true)]
private float _myNumber;
}
[RealtimeModel(createMetaModel: true)]
public partial class MyModel {
[RealtimeProperty(1, true)]
private float _myNumber;
}
This tells Normcore to generate a meta-model for your custom model, enabling ownership features. After recompiling your model with this flag, you will be able to call RequestOwnership() without encountering this error. For more details, see the documentation on requesting ownership of any RealtimeComponent or RealtimeModel. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4d ago
<@214044513256210432> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
rogan2528
rogan2528OP4d ago
Thanks, that was it

Did you find this page helpful?