beeeen
beeeen2w ago

How to know when to request ownership ASAP?

We have a script that requests ownership of an object right away. However, this throws errors such as:
Exception: RequestOwnership called before the model has been added to the datastore.
Exception: RequestOwnership called before the model has been added to the datastore.
and our script is:
public void RequestObjectOwnership()
{
rv = GetComponent<RealtimeView>();
rt = GetComponent<RealtimeTransform>();

if (rv != null && rv.realtime != null && rv.realtime.connected)
{
rv.realtimeView.RequestOwnership();
hasOwnership = true;
}

if (rt != null && rt.realtime != null && rt.realtime.connected)
{
rt.RequestOwnership();
hasOwnership = true;
}
}
public void RequestObjectOwnership()
{
rv = GetComponent<RealtimeView>();
rt = GetComponent<RealtimeTransform>();

if (rv != null && rv.realtime != null && rv.realtime.connected)
{
rv.realtimeView.RequestOwnership();
hasOwnership = true;
}

if (rt != null && rt.realtime != null && rt.realtime.connected)
{
rt.RequestOwnership();
hasOwnership = true;
}
}
You can see that we're attempting to determine if the model is set in the datastore with the if conditions: rv != null && rv.realtime != null && rv.realtime.connected. This obviously doesn't work. Is there a more elegant way to do this? I haven't seen any properties on the RealtimeView that would indicate that it's been added to the datastore.
11 Replies
kapa.ai
kapa.ai2w ago
Hi @beeeen. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- You're correct that simply checking realtime != null && realtime.connected is not sufficient to guarantee that the model has been added to the datastore and is ready for ownership requests. This is a common issue, especially when working with scene objects or when scripts execute before Normcore has finished initializing the model. The recommended approach is to wait until the model is present before interacting with ownership. For prefabs instantiated with Realtime.Instantiate(), the model is ready by the time Start() is called. For scene objects, you should wait until the didConnectToRoom event has fired or check for model presence in Start() after the connection is established. From the documentation:
If you’re dealing with a prefab, all views and components are initialized with their models and they will be ready to work with by the time Start() is called on any script on the prefab. If you’re dealing with a RealtimeView that exists in a scene file, you’ll need to wait until realtime.connected == true, or the didConnectToRoom event has fired. RealtimeView uses Start() internally to register with Realtime, and it’s possible your start method ran before RealtimeView.Start() Common Questions – RealtimeView.
A more robust solution: - For prefabs: Call RequestOwnership() in Start() or later. - For scene objects: Subscribe to the didConnectToRoom event and call RequestOwnership() after the room is connected. Example for scene objects:
void Start() {
var realtime = FindObjectOfType<Realtime>();
if (realtime != null) {
realtime.didConnectToRoom += OnDidConnectToRoom;
}
}

void OnDidConnectToRoom(Realtime realtime) {
rv = GetComponent<RealtimeView>();
rt = GetComponent<RealtimeTransform>();
if (rv != null) {
rv.RequestOwnership();
hasOwnership = true;
}
if (rt != null) {
rt.RequestOwnership();
hasOwnership = true;
}
}
void Start() {
var realtime = FindObjectOfType<Realtime>();
if (realtime != null) {
realtime.didConnectToRoom += OnDidConnectToRoom;
}
}

void OnDidConnectToRoom(Realtime realtime) {
rv = GetComponent<RealtimeView>();
rt = GetComponent<RealtimeTransform>();
if (rv != null) {
rv.RequestOwnership();
hasOwnership = true;
}
if (rt != null) {
rt.RequestOwnership();
hasOwnership = true;
}
}
This ensures you only request ownership after the model is present in the datastore. Summary:
- For prefabs: Safe to request ownership in Start(). - For scene objects: Wait for didConnectToRoom or check for model presence after connection. This approach will prevent the "RequestOwnership called before the model has been added to the datastore" exception and is the recommended pattern in Normcore projects Common Questions – RealtimeView. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@690217885540417680> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
maxweisel
maxweisel2w ago
hmm this should work actually. can you create an empty unity project that repros this bug? I’ll get it fixed The only thing I can think of is that if Start() hasn’t been called on your scene view, it won’t have connected to Realtime and received its model yet. are you additively loading a scene here? or potentially calling this on an instantiated prefab from Awake()
beeeen
beeeenOP2w ago
For more context, this is a prefab view. From what I can gather, our scripts call this immediately upon instantiating the object with Realtime.Instantiate(). I can get why the model is not initialized yet. I'm asking as to know where to implement this fix best. In addition, the error message recommends using SetOwnership instead, would that work? Full error message:
Exception: RequestOwnership called before the model has been added to the datastore. Please make sure this model is a child of a RealtimeView or room model before requesting ownership. If you already know the local clientID (e.g. for a collection model), you can use SetOwnership instead.
Exception: RequestOwnership called before the model has been added to the datastore. Please make sure this model is a child of a RealtimeView or room model before requesting ownership. If you already know the local clientID (e.g. for a collection model), you can use SetOwnership instead.
maxweisel
maxweisel2w ago
By the time Realtime.Instantiate() returns all views and components should have models
beeeen
beeeenOP2w ago
Would SetOwnership work inside of Awake()?
maxweisel
maxweisel2w ago
no
beeeen
beeeenOP2w ago
It's not asynchronous, correct?
maxweisel
maxweisel2w ago
Awake() runs before Realtime.Instantiate() can set the model and return it’s synchronous Realtime.Instantiate is basically just: GameObject.Instantiate() SetModel() return
beeeen
beeeenOP2w ago
So I should wait until Start() has been called - gotcha. I'll try making that Unity Project. Thank you, Max. You're so speedy with these replies!
maxweisel
maxweisel2w ago
no this should work. send me a repro and I can get it fixed or advise on what to do Waiting for Start() only applies to RealtimeViews that existed in the scene and weren’t instantiated from prefabs

Did you find this page helpful?