Difference between avatar.ownerIDInHierarchy, avatar.ownerIDSelf, and avatar.realtime.clientID?
I'm trying to keep track of the ID of the current client as clients leave and enter the room. I'm finding that avatar.owner.IDSelf always returns -1.
avatar.ownerIDInHierachy seems to work but if someone leaves, and rejoins they get assigned to ID 0 even though the former client that had the ID of 1 also gets set to the ID of 0. This causes errors with my system that isn't expecting two clients to both have the ID of 0.
avatar.realtime.clientID seems to work but never reassigns the ID's when someone leaves. For example if a room has two clients and client 0 leaves. Client 1 remains as ID 1 but once the client that left, rejoins the game. Their ID gets set to 0.
Which ID system should I use for a system that expects unique ID's for each client and can handle clients leaving and joining without assigning duplicate ID's?
19 Replies
Hi @Funkey. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
The
avatar.ownerIDSelf
property returns the client ID of the component owner. If the component is not owned by any client, it returns -1. This is why you're seeing -1 when you try to access this property.
The avatar.ownerIDInHierarchy
property returns the client ID of the component's hierarchy owner (the root owner of the component). This means that if a client owns a parent component, all child components will return the parent's client ID when ownerIDInHierarchy
is accessed.
The avatar.realtime.clientID
property returns the client ID assigned by the server when the client connects to the room. This ID is unique for each client and remains the same for the duration of the client's connection. If a client disconnects and then reconnects, they will be assigned a new client ID.
If you need a system that assigns unique IDs to each client and can handle clients leaving and joining without assigning duplicate IDs, you should use avatar.realtime.clientID
. This property will always return a unique ID for each client, regardless of whether they disconnect and reconnect.
However, please note that in offline mode, Realtime.clientID
and Room.clientID
will always return 0
. Also, if two instances of Realtime or Room connect to the same offline mode room name, they will have separate instances that do not share any data or state.
Sources:
- RealtimeModel (https://normcore.io/documentation/reference/classes/Normal.Realtime.RealtimeModel)
- RealtimeComponent (https://normcore.io/documentation/reference/classes/Normal.Realtime.RealtimeComponent%601)
- IRealtimeComponent (https://normcore.io/documentation/reference/classes/Normal.Realtime.IRealtimeComponent)
- Offline Mode (https://normcore.io/documentation/room/offline-mode#things-to-know)
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@304126447302344705> kapa.ai is still learning and improving, please let us know how it did by reacting below
@Normcore Assistant
If I want a system that reassigns client ID's when someone leaves, should I just not use it? I notice that if a client leaves, the ID's don't get reassigned. E.g client 0 leaves and everyone ID's remains the sames. But if someone new joins, they get assigned to client 0 which isn't ideal for my logic.
Let me check the knowledge base for you. One moment! :books:
----------------------
The behavior you're observing is expected. In NormalVR's system, when a client disconnects, their ID is not reassigned to another client. Instead, it's freed up and can be assigned to a new client that connects to the room. This is why you're seeing a new client get assigned the ID of a client that has disconnected.
If you need a system that reassigns client IDs when a client disconnects, you might need to implement this logic yourself. You could create a manager that keeps track of all connected clients and their IDs. When a client disconnects, the manager could reassign their ID to another client.
However, please note that this could lead to complications, especially if you're using the client ID to keep track of state or data associated with a client. If a client's ID changes, any state or data associated with their old ID would need to be updated to reflect their new ID.
In general, it's recommended to use the client ID system provided by NormalVR, as it ensures that each client has a unique ID for the duration of their connection. If you need to keep track of clients across connections, you might want to consider using a different identifier, such as a username or a unique identifier generated when the client first connects.
Sources:
- RealtimeAvatarManager (https://normcore.io/documentation/realtime/xr/avatars#realtimeavatarmanager)
- RealtimeComponent (https://normcore.io/documentation/reference/classes/Normal.Realtime.RealtimeComponent%601)
- IRealtimeComponent (https://normcore.io/documentation/reference/classes/Normal.Realtime.IRealtimeComponent)
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
<@304126447302344705> kapa.ai is still learning and improving, please let us know how it did by reacting below
realtime.clientID is your local client ID also a client's id doesn't change while they are connected, if someone leaves their ID becomes available for reuse when someone else joins, you wont necessarily get the same id if you leave and rejoin. the key value in avatarmanager.avatars will be that avatar's client id, you can use that.
and it’s not possible for two connected clients to have the same clientID
if you need your own GUID, store it on a custom model/component on the avatar
Sounds good! Thank you for the help!
@Normcore Assistant
Sorry if this question seems trivial, but RealtimeAvatarManager.avatars[realtime.clientID] will be set to null if there is no avatar with the realtime.clientID that's used as the index into the avatars dictionary. Is that correct?
Let me check the knowledge base for you. One moment! :books:
----------------------
Yes, you are correct. The
RealtimeAvatarManager.avatars
is a dictionary that maps client IDs to their corresponding RealtimeAvatar
instances. If you try to access an avatar using a client ID that does not exist in the dictionary (i.e., there is no avatar with that client ID), it will return null
.
Here's how you might access an avatar from the dictionary:
In this code, RealtimeAvatarManager.avatars[realtime.clientID]
will be null
if there is no avatar with the realtime.clientID
that's used as the index into the avatars
dictionary.
Source: RealtimeAvatarManager (https://normcore.io/documentation/realtime/xr/avatars#realtimeavatarmanager)
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@304126447302344705> kapa.ai is still learning and improving, please let us know how it did by reacting below
@Normcore Assistant
C#
This has a single client and I get an key not found error for i=1, which makes sense. I'm assuming that there is no null set to the avatars dictionary, it appears that a clientID will create a key value pair once someone joins.
I'm assuming if someone leaves such as client 0 leaving, then the value will either be set to null or the key|value pair is removed from the avatars dictionary. Is that correct?
Let me check the knowledge base for you. One moment! :books:
----------------------
Yes, you are correct. The
RealtimeAvatarManager.avatars
dictionary maps client IDs to their corresponding RealtimeAvatar
instances. When a client joins the room, a new key-value pair is added to the dictionary with the client's ID as the key and their avatar as the value.
When a client leaves the room, their avatar is destroyed and the corresponding key-value pair is removed from the avatars
dictionary. This is why you're getting a KeyNotFoundException when you try to access an avatar using a client ID that no longer exists in the dictionary.
Here's how you might safely access an avatar from the dictionary:
In this code, RealtimeAvatarManager.avatars.TryGetValue(realtime.clientID, out avatar)
will return false
and avatar
will be null
if there is no avatar with the realtime.clientID
that's used as the key into the avatars
dictionary.
Source: RealtimeAvatarManager (https://normcore.io/documentation/realtime/xr/avatars#realtimeavatarmanager)
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@304126447302344705> kapa.ai is still learning and improving, please let us know how it did by reacting below
@Normcore Assistant
How does RealtimeAvaterManager.avatars.count work? Will it give me the proper headcount of players in the game or should I just loop through it and check the non null objects?
Let me check the knowledge base for you. One moment! :books:
----------------------
The
RealtimeAvatarManager.avatars.count
property will give you the number of key-value pairs in the avatars
dictionary, which corresponds to the number of avatars (or players) currently in the room. Each key-value pair represents a client and their corresponding avatar.
When a client joins the room, a new key-value pair is added to the dictionary. When a client leaves the room, their avatar is destroyed and the corresponding key-value pair is removed from the dictionary. Therefore, avatars.count
should give you the correct number of players in the room at any given time.
Here's how you might use it:
In this code, RealtimeAvatarManager.avatars.Count
will give you the number of players currently in the room.
You don't need to loop through the dictionary and check for non-null objects. If a client leaves the room, their key-value pair is removed from the dictionary, so there should not be any null objects in the dictionary.
Source: RealtimeAvatarManager (https://normcore.io/documentation/realtime/xr/avatars#realtimeavatarmanager)
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@304126447302344705> kapa.ai is still learning and improving, please let us know how it did by reacting below
@Normcore Assistant
For some reason, someone joining and leaving increases the player count. Like a two player game, and player 2 leaves and rejoins now makes that count 3 for some reason.
Let me check the knowledge base for you. One moment! :books:
----------------------
That's unusual. The
RealtimeAvatarManager.avatars.Count
should reflect the current number of players in the room. If a player leaves and rejoins, the count should remain the same, not increase.
When a player leaves the room, their avatar is destroyed and the corresponding key-value pair is removed from the avatars
dictionary. When the player rejoins, a new key-value pair is added to the dictionary. This should not increase the total count.
Here's a simple way to print the current player count whenever it changes:
If you're still seeing the player count increase when a player leaves and rejoins, there might be an issue with how avatars are being managed in your game. You might want to check your code to make sure avatars are being properly destroyed when a player leaves, and that a new avatar is only created when a player joins.
Source: RealtimeAvatarManager (https://normcore.io/documentation/realtime/xr/avatars#realtimeavatarmanager)
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@304126447302344705> kapa.ai is still learning and improving, please let us know how it did by reacting below