gubebra
gubebra3w ago

Sync a value when OnApplicationPause is triggered

I want to change the health value from a player model as soon as he paused the game in an Oculus Quest. I already have the info that once you lock/turn off the headset, the OnApplicationPause event is triggered in Unity and I've already did some checks to make sure it's actually being called. Right now, I wrote a very simple code:
// called by Unity
private void OnApplicationPause(bool pauseStatus)
{
if (pauseStatus)
playerModel.health = 0;
}
// called by Unity
private void OnApplicationPause(bool pauseStatus)
{
if (pauseStatus)
playerModel.health = 0;
}
The issue is that this value never gets synced across all clients and I think that is happening because Unity must halt some processes when this event runs like coroutines, and the value is not synced until I unlock the device (as soon as I unlock the headset the value is synced). Does Nomcore have anything that can help me with this, like a ".SendOutgoingCommands()" or something? I know some APIs have this, so I was wondering if we have this here.
10 Replies
kapa.ai
kapa.ai3w ago
Hi @gubebra. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Yes, Normcore does provide a way to synchronize data across all clients. It uses a datastore to keep all state synchronized. When you make a change to the datastore, it’s automatically replicated to all connected clients. However, the synchronization of data in Normcore is categorized into two types: reliable and unreliable. If you plan to change a property very often, you should use an unreliable property. Unreliable updates are not resent if they’re dropped in transit because it’s expected that another update is following shortly after. On the other hand, reliable properties are good for things that you update once and that should be resent if the packet is dropped in transit. In your case, you might want to consider marking the health property as reliable. When you change it, Normcore will ensure that this value is synchronized between all clients and that it is in sync before any newer reliable updates are applied to the datastore. Here's how you can do it:
public class PlayerModel : RealtimeModel {
private ReliableProperty<int> _health = new ReliableProperty<int>(this);

public int Health {
get { return _health.Value; }
set { _health.Value = value; }
}
}
public class PlayerModel : RealtimeModel {
private ReliableProperty<int> _health = new ReliableProperty<int>(this);

public int Health {
get { return _health.Value; }
set { _health.Value = value; }
}
}
Then in your OnApplicationPause method:
private void OnApplicationPause(bool pauseStatus)
{
if (pauseStatus)
playerModel.Health = 0;
}
private void OnApplicationPause(bool pauseStatus)
{
if (pauseStatus)
playerModel.Health = 0;
}
This way, when the Health property is changed, it will be reliably synchronized across all clients. For more information, you can refer to the Normcore documentation on synchronizing custom data (https://normcore.io/documentation/realtime/synchronizing-custom-data#reliable--unreliable). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3w ago
<@599054560270483456> kapa.ai is still learning and improving, please let us know how it did by reacting below
gubebra
gubebra3w ago
I think I already have a reliable health variable. Here's how I define it:
[RealtimeModel]
public partial class PlayerModel
{
[RealtimeProperty(1, true, true)] private int _health;
}
[RealtimeModel]
public partial class PlayerModel
{
[RealtimeProperty(1, true, true)] private int _health;
}
@Normcore Assistant
kapa.ai
kapa.ai3w ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Your PlayerModel class and the _health property are correctly defined for synchronization in Normcore. The [RealtimeProperty(1, true, true)] attribute indicates that _health is a reliable property and it will be synchronized across all clients. However, if the value is not being updated immediately when the application is paused, it might be due to the way Unity handles the OnApplicationPause event. When an application is paused, Unity might halt some processes, which could delay the synchronization of the _health property until the application is resumed. Unfortunately, Normcore does not provide a .SendOutgoingCommands() method or similar to force an immediate update. Normcore handles all the networking and synchronization internally and does not expose such low-level control. One workaround could be to try and change the health value slightly before the application is paused, if that's possible in your application logic. This way, the update might be processed before Unity halts the processes. For more information, you can refer to the Normcore documentation (https://normcore.io/documentation/realtime/synchronizing-custom-data#reliable--unreliable). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3w ago
<@599054560270483456> kapa.ai is still learning and improving, please let us know how it did by reacting below
gubebra
gubebra3w ago
How do games usually deal with this?
Mechabit
Mechabit3w ago
you can add a last updated time stamp which you update every second or so and then it's older than a few seconds you know they've stopped updating or you can use head pos/rot cos people move their heads constantly
gubebra
gubebra3w ago
Hi Mechabit, thanks for the suggestions! I know those might work (and probably what I will need to do), but do you happen to know what is the ideal solution here? Is it having a server side "master client" to handle that?
Mechabit
Mechabit3w ago
public normcore doesn't have server side code you can with private best thing to do is have all clients calculate the idle state of all other clients or have the client with the lowest client ID do it
gubebra
gubebra3w ago
Yeah I thought so. Glad I've asked.