What is the best way to keep in sync a variable in the form of float array?
I need to keep in sync a float array of two values in a custom model. I need this to go always together since one of the values is a very precise timestamp that I need to keep associated with the other one.
16 Replies
Hi @JuanLouTech. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
To keep a float array synchronized in a custom model in NormalVR, you can create a custom realtime component and model. This is done by creating a script for the component and one for the model.
In your case, you can create a model that holds your float array and the associated timestamp. You can mark the property as reliable if you want to ensure that the value is synchronized between all clients and that it is in sync before any newer reliable updates are applied to the datastore. This is especially useful for data that you update once and that should be resent if the packet is dropped in transit.
Here is an example of how you can create a custom model:
And here is an example of how you can create a custom realtime component:
In this example, the
CustomComponent
class has two properties: floatArray
and timestamp
. These properties return the values from the CustomModel
instance. If the model is not yet connected to the room, they return default values.
Please refer to the Normcore Documentation (https://normcore.io/documentation/realtime/synchronizing-custom-data) for more details on how to synchronize custom data.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@941753147938984038> kapa.ai is still learning and improving, please let us know how it did by reacting below
@Normcore Assistant , but I'm getting an error because the float[] is not natively serialized
Let me check the knowledge base for you. One moment! :books:
----------------------
In Normcore, only primitive types (
int
, float
, Vector3
, string
, etc.) can be serialized. If you're trying to sync a specific kind of object or a complex data type like a float array, you should create a field for each property on the object that you'd like to sync.
In your case, since you have a float array of two values, you can create two separate float fields in your model. Here's an example:
And in your component:
This way, you can keep your two float values and the associated timestamp in sync. For more information, please refer to the Normcore Documentation (https://normcore.io/documentation/room/common-questions#when-i-try-to-sync-a-specific-object-to-the-datastore-i-get-an-error-that-says-it-cannot-be-serialized-whats-the-issue).
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@941753147938984038> kapa.ai is still learning and improving, please let us know how it did by reacting below
@Normcore Assistant Would Vector2 work natively?
Let me check the knowledge base for you. One moment! :books:
----------------------
Yes,
Vector2
is one of the primitive types that can be natively serialized in Normcore. You can use a Vector2
to store your two float values. Here's an example:
And in your component:
This way, you can keep your two float values and the associated timestamp in sync. For more information, please refer to the Normcore Documentation (https://normcore.io/documentation/room/common-questions#when-i-try-to-sync-a-specific-object-to-the-datastore-i-get-an-error-that-says-it-cannot-be-serialized-whats-the-issue).
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@941753147938984038> kapa.ai is still learning and improving, please let us know how it did by reacting below
@Normcore Assistant , this is not working either. I'm getting this error whe ntrying to compile the model :
ArgumentException: Unsupported serialization type: System.Single[] (Field: _animationTriggerHash). Property must be a primitive type or an object that inherits the RealtimeModel class.
Normal.Realtime.RealtimeModelCompiler.GetModelLayoutForClass (System.Type modelClass) (at <2fafecb97aaa43138ec971f0d51fa4d7>:0)
Normal.Realtime.RealtimeModelCompiler.GenerateModel (UnityEditor.MonoScript script) (at <2fafecb97aaa43138ec971f0d51fa4d7>:0)
Normal.Realtime.RealtimeModelCompiler.TryGenerateModel (UnityEditor.MonoScript script) (at <2fafecb97aaa43138ec971f0d51fa4d7>:0)
UnityEngine.Debug:LogException(Exception)
Normal.Realtime.RealtimeModelCompiler:TryGenerateModel(MonoScript)
Normal.Realtime.Serialization.ModelEditor:OnInspectorGUI()
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)
The _animationTriggerHash property is defined as a reliable Vector2 in the model. Since I'm on the 3.0.0 Webgl-alpha this might be a version problem.
Let me check the knowledge base for you. One moment! :books:
----------------------
I'm sorry for the confusion. It seems there might be a misunderstanding. In Normcore,
Vector2
is not a supported type for serialization. The supported types are int
, uint
, bool
, string
, float
, double
, Color
, Vector3
, and Quaternion
.
If you need to synchronize a pair of float
values, you should create two separate float
fields in your model. Here's an example:
And in your component:
This way, you can keep your two float values and the associated timestamp in sync. For more information, please refer to the Normcore Documentation (https://normcore.io/documentation/room/realtimemodel).
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@941753147938984038> kapa.ai is still learning and improving, please let us know how it did by reacting below
Does this model work?
Ah just noticed you're on
3.0.0 Webgl-alpha
Maybe there's a difference thereI ended up encoding the int and the float I need in a single double since Vector2 did not seem to work and Vector3 was a waste of bandwidth for what I wanted. It was a weird hack but worked as a charm. 🤷‍♂️
Fwiw I checked with our devs and it might be a quirk with the model compiler in
3.0.0 Webgl-alpha
(since it's older than the current 2.9.5
regular Normcore).
It's using the reflection data from the last successful compilation, float[]
in this case.
Before you can change the model property to Vector2
, you need to make the project compile successfully again. This could involve commenting out the property for example. After which I'm confident Vector2
would work.Thanks @NormalMark . It worked but I can't use it because one of the ints I need to send is an animation hash (32 bits) and when the Vector2 is received on the other clients it changed the value since floats can't keep 32 bit whole part of the number.
I Also tried a walk around the "double" type precision problem (I was having some too with my hacky solution) using a long in which I store in the first 32 bits the animation hash and in the last 32 bits the timestamp (multiplying the time stamp by 1000 and casting it to an int, keeping the 3 decimals precision) . But it turns out longs are not serialized natively neither. I'd rather not use a string to encode this because of it's weight for network load but for now it seems the only truly reliable solution for what I need to achieve with the default supported types.
sorry to chime in late here but just put two float properties on your model. if you change them in the same frame they’ll always go out together and will be received together
due to a legacy architecture thing the change events will fire as they’re deserialized so you may see it read one before the other, but if you wait for the whole model to deserialize that frame, they’ll both arrive at the same time and you won’t have to do all of this work to try to put them into the same field