Niv
Niv3d ago

Accessing the model's 'isRoomConnected', 'isOwnedLocallySelf' during OnRealtimeModelReplaced

Is it allowed to access the properties 'isRoomConnected' or 'isOwnedLocallySelf' (or any other ownership property) inside the OnRealtimeModelReplaced when currentModel is not null?
12 Replies
kapa.ai
kapa.ai3d ago
Hi @Niv. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Yes, it is allowed to access properties like isRoomConnected or isOwnedLocallySelf (and other ownership properties) inside the OnRealtimeModelReplaced method when currentModel is not null. However, there are some important considerations to keep in mind: 1. Model Availability: The OnRealtimeModelReplaced method is called when a new model is set on the component. This means that if currentModel is not null, you have a valid model to work with. 2. Room Connection: The isRoomConnected property should be available and accurate at this point. According to the RealtimeModel documentation, isRoomConnected returns true if a room is set on the model and the room is connected. 3. Ownership Properties: Properties like isOwnedLocallySelf should also be accessible. The RealtimeModel documentation shows that these properties are available on the model. 4. Timing Considerations: While these properties are accessible, it's important to note that OnRealtimeModelReplaced is called during the initialization process. The RealtimeComponent documentation mentions that for prefab views, certain properties (like realtime) are available after Awake, while for scene views, they might not be available until Start. 5. Fresh Model Check: The isFreshModel property can be particularly useful in this context. As stated in the RealtimeModel documentation, "This flag can be used to apply component settings or initial values to a newly instantiated model." Here's an example of how you might use these properties in OnRealtimeModelReplaced:
protected override void OnRealtimeModelReplaced(YourModelType previousModel, YourModelType currentModel) {
if (currentModel != null) {
if (currentModel.isFreshModel) {
// Set initial values for a new model
}

if (currentModel.isRoomConnected) {
// Perform actions that require a room connection
}

if (currentModel.isOwnedLocallySelf) {
// Perform actions specific to locally owned models
}

// Other initialization logic...
}

// Unsubscribe from previous model events if needed
if (previousModel != null) {
// Unsubscribe logic...
}
}
protected override void OnRealtimeModelReplaced(YourModelType previousModel, YourModelType currentModel) {
if (currentModel != null) {
if (currentModel.isFreshModel) {
// Set initial values for a new model
}

if (currentModel.isRoomConnected) {
// Perform actions that require a room connection
}

if (currentModel.isOwnedLocallySelf) {
// Perform actions specific to locally owned models
}

// Other initialization logic...
}

// Unsubscribe from previous model events if needed
if (previousModel != null) {
// Unsubscribe logic...
}
}
Remember to always check if currentModel is not null before accessing these properties to avoid null reference exceptions. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3d ago
<@269927864265211906> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Niv
NivOP3d ago
Hmm ... it seems like I'm getting isRoomConnected 'false' for models that are added during my connection (pre-existed in the dataStore). It also seems like ownership on them is not setup properly. @kapa.ai
kapa.ai
kapa.ai3d ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- I understand your concern about isRoomConnected being false and ownership not being set up properly for pre-existing models in the datastore. Let's explore this issue based on the information available in the knowledge sources. 1. Timing of Model Initialization: The behavior you're experiencing might be related to the timing of when models are initialized and when the room connection is fully established. According to the RealtimeComponent documentation, for RealtimeViews that exist in a scene file, you need to wait until realtime.connected == true, or the didConnectToRoom event has fired. 2. Checking Connection Status: Instead of relying solely on isRoomConnected in OnRealtimeModelReplaced, you might want to check the connection status of the Realtime instance. The RealtimeComponent<TModel> documentation mentions a realtime property that gives access to the Realtime instance managing the component. 3. Ownership Setup: For ownership, it's important to note that models can have different ownership states. The RealtimeModel documentation shows properties like ownerIDSelf, isUnownedSelf, isOwnedLocallySelf, and isOwnedRemotelySelf that you can use to check the ownership status. To address these issues, you could try the following approach: 1. Wait for room connection: Instead of checking isRoomConnected on the model, wait for the Realtime instance to connect fully before interacting with pre-existing models. 2. Use the didConnectToRoom event: Subscribe to the didConnectToRoom event on your Realtime instance. This event will fire when the connection is fully established. 3. Check ownership after connection: Once the room is connected, you can check and set up ownership for pre-existing models if necessary. Here's a rough example of how you might implement this:
private Realtime _realtime;

private void Start()
{
_realtime = GetComponent<Realtime>();
_realtime.didConnectToRoom += DidConnectToRoom;
}

private void DidConnectToRoom(Realtime realtime)
{
// Now that we're connected, we can safely interact with pre-existing models
foreach (var model in _preExistingModels)
{
SetupModelOwnership(model);
}
}

private void SetupModelOwnership(RealtimeModel model)
{
if (model.isUnownedSelf)
{
// If the model is unowned, you might want to request ownership
model.RequestOwnership();
}
// Other ownership setup logic...
}
private Realtime _realtime;

private void Start()
{
_realtime = GetComponent<Realtime>();
_realtime.didConnectToRoom += DidConnectToRoom;
}

private void DidConnectToRoom(Realtime realtime)
{
// Now that we're connected, we can safely interact with pre-existing models
foreach (var model in _preExistingModels)
{
SetupModelOwnership(model);
}
}

private void SetupModelOwnership(RealtimeModel model)
{
if (model.isUnownedSelf)
{
// If the model is unowned, you might want to request ownership
model.RequestOwnership();
}
// Other ownership setup logic...
}
Remember, this is a simplified example and you'll need to adapt it to your specific use case. If you're still experiencing issues after trying these approaches, it might be worth reaching out to the Normcore support team for more specific guidance, as there might be nuances to your particular setup that aren't covered in the general documentation. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3d ago
<@269927864265211906> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Mechabit
Mechabit3d ago
I've run into this as well, models get created locally before connecting so that they are ready to be sent to the server instead of after connecting. You'll then get existing models sent to you if you're not the first to join. It's kinda confusing honestly. You'll have to wait till you are properly connected to get accurate ownership and room connection states.
Niv
NivOP2d ago
Yeah I didn't like this part of the implementation at all. Should be cleaner
maxweisel
maxweisel2d ago
isOwnedLocally works for the model being set, but there’s a chicken and egg issue with other components. fwiw OnRealtimeModelReplaced isn’t a good time to deal with ownership. Use Start() for prefabs or didConnectToroom for objects in the scene OnRealtimeModelReplaced is only there for event subscribe / unsubscribe or setting default values on the model. it’s not meant to be a place to do game logic
Niv
NivOP2d ago
I see. Would it be safe to assume that if previousModel == null and currentModel != null but not a fresh model, then it's under remote authority? I'll see if we can avoid doing any login in OnRealtimeModelReplaced, but to be honest - I had to write a pretty elaborate system so that our completely modular mech would get properly synchronized. Some loadout choices dictate more rigidbodies/RealtimeComponents in a dynamic way. And there are so many combinations we couldn't pre-bake those (nor do we want to)
maxweisel
maxweisel2d ago
no, I don’t think that’s a safe assumption. is the issue that you’re trying to detect if a prefab represents the local player? tell me more about what you’re trying to build A typical pattern folks use is to do something like this: var myMech = Realtime.Instantiate(…) myMech.ConfigureLoadout(…); That ConfigureLoadout call will only run for the local client. It will run immediately after OnRealtimeModelReplaced has been called for all views / components on the prefab, and any changes made to the prefab will be serialized and sent in the same packet as the Instantiate call, and so all remote clients will receive the instantiate call and the configuration settings at the same time changes made to the models on the prefab** You shouldn’t need to be trying to configure your loadout in OnRealtimeModelReplaced and this system extends to instantiating multiple objects. If ConfigureLoadout() ends up calling more Realtime.Instantiate() calls, they’ll also be included in the same outgoing packet since it’s all happening on the same render frame Which should cover most modular cases. Let me know if that covers it. Happy to chat through more options if it doesn’t cover your case.
Niv
NivOP2d ago
Yes that would be a better design pattern, but we also have a bunch of legacy code as we didn't design with networking in mind to begin with. It will really take a long time to explain ... That said, I seem to have it working but I'll definitely ask if I run into further issues. Thanks
maxweisel
maxweisel2d ago
sounds good! keep me posted

Did you find this page helpful?