Ryllexya
Ryllexya3mo ago

OnCollisionExit

I have a chair system, where on OnCollisionEnter it is marked as "occupied = true" and OnCollisionExit it is marked as "occupied=false". When avatars enter the room, they get teleported to the next available chair that someone isnt sitting in. It all works fine, and the status of the boolean adjusts if people switch seats. The problem arises when the avatars leave the room. Obviously they are inside the collision box, so when they disconnect and leave the room, no OnCollisionExit gets fired off. I've been trying to get OnTrigerStay to work with this, but it all seems futile, no matter how I try, because it isn't telling you when someone stops existing in the box, rather only fires off when someone is inside. also running coroutines and counters feels counter-productive, if I could just alert the boolean (which is also a Normcore model boolean) to change when the avatar disconnects. Is there some place in Normcore scripts, where it can detect the person leaving? Something, that gives me an opportunity to fire off a function before the disconnecting happens? Any ideas appreciated very much...
23 Replies
kapa.ai
kapa.ai3mo ago
Hi @Ryllexya. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Based on the information provided in the knowledge sources, Normcore does have events that are fired when a connection to a room is established or disconnected. Specifically, the didConnectToRoom and didDisconnectFromRoom events in the Realtime class can be used to detect when an avatar connects or disconnects from a room. Here is the relevant extract from the documentation:
didConnectToRoomevent RealtimeEvent didConnectToRoom An event that is fired when Realtime is connected to a room and all realtime prefabs and realtime views in the scene have been successfully connected to the datastore. didDisconnectFromRoomevent RealtimeEvent didDisconnectFromRoom An event that is fired when Realtime is disconnected from a room.
You could potentially use the didDisconnectFromRoom event to trigger a function that marks the chair as unoccupied when an avatar disconnects from the room. However, you would need to ensure that the function knows which chair to mark as unoccupied, which might require additional logic in your code. Please note that this is based on the information available in the provided knowledge sources and my understanding of Unity and Normcore. You might need to adjust this approach based on the specifics of your project. For more information, you can refer to the Realtime class documentation (https://normcore.io/documentation/reference/classes/Normal.Realtime.Realtime). If you need further assistance, I would recommend reaching out to the Normcore community on their Discord (https://normcore.io/discord) or forum (https://forum.normcore.io/). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@164038313924231178> kapa.ai is still learning and improving, please let us know how it did by reacting below
cryptomax
cryptomax3mo ago
avatarmanager has avatar destroyed event, when that happens you could iterate through your chair coliders and check if a player is inside them? just have a player run that check and if someone isn't in a chair they fix setting the boolean
Ryllexya
Ryllexya3mo ago
Actually, I tried what the bot suggested. And with a debug log I can see that the function to update the model gets called, and yet, the model doesnt update after the other person leaves... The models otherwise update fine. All I'm doing in that function is public void SetModel(bool newValue){ model.isOccupied = newValue; Debug.Log("Disconnected..."); } I can see the "Disconnected..." in console, but the model didn't change. Any ideas why? Also, as far as I'm aware the colliders only have OnEnter, OnExit, and OnStay. I don't know of any way to check if something is inside the collider.
cryptomax
cryptomax3mo ago
diddisconenct from room is more something you'd get yourself but that woudlnt' leave time to try and set the bool becuase you'd already be disconencted from the room? so the bot advice is sus I think?
Ryllexya
Ryllexya3mo ago
Does the avatar get destroyed then before actually disconnecting? With enough time to change a value?
cryptomax
cryptomax3mo ago
point is everyone will get the avatar destoryed event (if they are subcribed) so then you juts have one of them do the check/ set
Ryllexya
Ryllexya3mo ago
Oh, everyone gets a destroyed avatar event fired in th eir managers?
cryptomax
cryptomax3mo ago
if they are subsribed to it yeah
Ryllexya
Ryllexya3mo ago
I'm not using a custom avatar manager, so I presume its subscribed? Oh there is also UnregisterAvatar in avatar manager - can that also be used? I presume both unregistering and destroying happens when you leave.
cryptomax
cryptomax3mo ago
well I geuss im' saying you would need some code somewhere to decide to do something with the event so in that locaiton is where you woudl want to subscribe to it, like a fixer script that just subscribes and then if the event is received it does the check and set
Ryllexya
Ryllexya3mo ago
never done that before... Do I subscribe to that event in the chair script?
cryptomax
cryptomax3mo ago
yeah you could, then do something like this to determine lowest connected player to actually run the fix code
bool IsLowestIdClient(Realtime realtime)
{
RealtimeAvatarManager avatarManager = realtime.gameObject.GetComponent<RealtimeAvatarManager>();
if (avatarManager != null && avatarManager.avatars.Count > 0)
{
int lowestId = avatarManager.avatars.Keys.Min();
bool isLowestId = (realtime.clientID == lowestId);

Debug.Log($"Lowest ID: {lowestId}, Is Lowest ID Client: {isLowestId}");

return isLowestId;
}

return false;
}
bool IsLowestIdClient(Realtime realtime)
{
RealtimeAvatarManager avatarManager = realtime.gameObject.GetComponent<RealtimeAvatarManager>();
if (avatarManager != null && avatarManager.avatars.Count > 0)
{
int lowestId = avatarManager.avatars.Keys.Min();
bool isLowestId = (realtime.clientID == lowestId);

Debug.Log($"Lowest ID: {lowestId}, Is Lowest ID Client: {isLowestId}");

return isLowestId;
}

return false;
}
so if that returns true then they could run the fix that way only one person does it otherwise everyone will try
Ryllexya
Ryllexya3mo ago
omg it worked
Ryllexya
Ryllexya3mo ago
If any sad soul in the future is lost, this is what you call
No description
Ryllexya
Ryllexya3mo ago
by the way, if I do it from the chair script, I presume only chairs call this? not all avatars? Or should I still do the check you mentioned above as well.
cryptomax
cryptomax3mo ago
wont that set all chair models to false if someone leaves though or do you have other logic
Ryllexya
Ryllexya3mo ago
OMG it did... 💀
cryptomax
cryptomax3mo ago
yeah so you just need to use that event being received to check if a player is in a chair you could do a simple distance check to anything tagged player or something like several ways you coudl do it then only if a player is not there would you set it to model false
Mechabit
Mechabit3mo ago
or you can request ownership of the chair view and if it's owner is -1 (unowned) then it's an available chair. When the owner leaves it's set back to -1
Ryllexya
Ryllexya3mo ago
Good idea! Imma go with that, thank you! Just wanted to let you know it worked brilliantly! And so simple! 👏
cryptomax
cryptomax3mo ago
I thought a view owner leaving destroys the view? why did I think that hmm
Mechabit
Mechabit3mo ago
it does if you set it to destroy for prefabs, scene views never get destroyed normcore doesn't support destorying scene views cos late joiners wont know they were destroyed