khoi
khoi5d ago

Separating Realtime.Destroy() from OnDestroy when a client leaves/stops playing?

Can I set destroyWhenOwnerOrLastClientLeaves to false to prevent OnDestroy from running on my RealtimeComponent? Basically I have an OnDestroy on my RealtimeComponent that I want to run when Realtime.Destroy() is called. But not when a client disconnects (which triggers OnDestroy for monobehaviours)
4 Replies
kapa.ai
kapa.ai5d ago
Hi @khoi. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- You are correct that setting destroyWhenOwnerOrLastClientLeaves: false when instantiating your object will prevent the server from automatically destroying the object when the owner disconnects or when the last client leaves the room. This means the object (and its associated RealtimeComponent) will persist in the room's datastore and will not be destroyed automatically by Normcore when a client disconnects. However, it's important to note that Unity's OnDestroy() method on a MonoBehaviour will still be called if the GameObject is destroyed locally for any reason, including scene unloads or application quit—not just when Realtime.Destroy() is called. Normcore does not override Unity's destruction lifecycle. If you want your OnDestroy() logic to only run when Realtime.Destroy() is explicitly called (and not when a client disconnects or the scene unloads), you will need to implement your own logic to distinguish between these cases. One common approach is to set a flag before calling Realtime.Destroy() and check that flag in OnDestroy():
private bool _destroyedByRealtime = false;

public void DestroyViaRealtime() {
_destroyedByRealtime = true;
Realtime.Destroy(gameObject);
}

private void OnDestroy() {
if (_destroyedByRealtime) {
// Logic that should only run when destroyed via Realtime.Destroy()
}
}
private bool _destroyedByRealtime = false;

public void DestroyViaRealtime() {
_destroyedByRealtime = true;
Realtime.Destroy(gameObject);
}

private void OnDestroy() {
if (_destroyedByRealtime) {
// Logic that should only run when destroyed via Realtime.Destroy()
}
}
This way, you can ensure your cleanup code only runs when you intend it to. To summarize: - Setting destroyWhenOwnerOrLastClientLeaves: false will prevent automatic destruction by the server, but will not prevent OnDestroy() from being called if the GameObject is destroyed for other reasons. - You need to manage your own logic to distinguish between destruction via Realtime.Destroy() and other causes. This approach is consistent with how Normcore handles object lifetime and Unity's destruction lifecycle, as described in the documentation on lifetime flags and Realtime.Destroy() methods. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai5d ago
<@412870643533479936> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
khoi
khoiOP5d ago
Okay, seems like using OnDestroy to respond to Realtime.Destroy() is an anti-pattern
maxweisel
maxweisel4d ago
OnDestroy() is called by Unity when we call GameObject.Destroy(). There's no way to silence it.

Did you find this page helpful?