gubebra
gubebraβ€’7mo ago

Call DidChange event when value is the same

I basically want to trigger the ValueDidChange every time I assign model.value to something, even if that value is the same as before. For some context, I'm sending a string to all clients when a player scores and if he scores again the string is going to be the same, but I need the StringDidChange event to trigger on all clients to display who scored.
42 Replies
kapa.ai
kapa.aiβ€’7mo 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: ---------------------- In NormalVR, the ValueDidChange event is triggered when a value changes. If you're setting the same value again, the event might not be triggered because the value hasn't technically changed. One workaround could be to slightly modify the value each time you set it, even if the meaningful content remains the same. For example, you could append a unique, but irrelevant, character or number to the string each time a player scores. This would ensure that the ValueDidChange event is triggered each time, as the value is technically different each time. Here's an example of how you might implement this in your code:
public void PlayerScored(string playerName) {
// Append a unique value to the player name each time they score
model.value = playerName + "_" + System.Guid.NewGuid().ToString();

// This will fire the valueChanged event on the model, which will update for all clients.
}
public void PlayerScored(string playerName) {
// Append a unique value to the player name each time they score
model.value = playerName + "_" + System.Guid.NewGuid().ToString();

// This will fire the valueChanged event on the model, which will update for all clients.
}
In this example, a new GUID is appended to the player name each time they score. This ensures that the value is unique each time, triggering the ValueDidChange event. You can then handle this event and strip the appended GUID before displaying the player name. Remember to handle the ValueDidChange event properly in your code. Here's an example of how you might do this:
private void ValueDidChange(MyModel model, string value) {
// Strip the appended GUID from the value
string playerName = value.Split('_')[0];

// Display the player name
DisplayPlayerScored(playerName);
}
private void ValueDidChange(MyModel model, string value) {
// Strip the appended GUID from the value
string playerName = value.Split('_')[0];

// Display the player name
DisplayPlayerScored(playerName);
}
In this example, the ValueDidChange method splits the value on the underscore character (_), and takes the first part as the player name. It then calls a hypothetical DisplayPlayerScored method to display the player name. Please note that this is a workaround and might not be the best solution depending on your specific use case. Always consider the implications of your design decisions and choose the best solution for your needs. For more information on how to use ValueDidChange and other events in NormalVR, you can refer to the official documentation (https://normcore.io/documentation/realtime/synchronizing-custom-data#creating-a-realtimecomponent-subclass). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.aiβ€’7mo ago
<@599054560270483456> kapa.ai is still learning and improving, please let us know how it did by reacting below
Mechabit
Mechabitβ€’7mo ago
the bot doesn't know but there's a better option set the equality check parameter to false when you make the model it's not in the docs but was added recently
gubebra
gubebraOPβ€’7mo ago
Interesting, when defining the RealtimeProperty?
Mechabit
Mechabitβ€’7mo ago
yeah, use intelisense in your IDE to get the property name RealtimePropertyAttribute(uint propertyID, bool reliable, bool createDidChangeEvent = false, bool includeEqualityCheck = true) set the last one to false
gubebra
gubebraOPβ€’7mo ago
[RealtimeProperty(1, true, true, false )] private string _text;
[RealtimeProperty(1, true, true, false )] private string _text;
Like this?
Mechabit
Mechabitβ€’7mo ago
yeah
gubebra
gubebraOPβ€’7mo ago
It's almost working, I get the event fired for the person that changed the string but not the other clients
Mechabit
Mechabitβ€’7mo ago
make sure they have registered to the event before you change it
gubebra
gubebraOPβ€’7mo ago
I don't know if I've done something wrong it's a really simple script:
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;
using Normal.Realtime;

public class TextEvent : RealtimeComponent<TextEventModel>
{
protected override void OnRealtimeModelReplaced(TextEventModel previousModel, TextEventModel currentModel)
{
if (previousModel != null)
{
previousModel.textDidChange -= TextDidChange;
}

if (currentModel != null)
{
currentModel.textDidChange += TextDidChange;
}
}

private void TextDidChange(TextEventModel model, string value)
{
Debug.Log("text: " + value); // this is not being called
UIManager.Instance.notificationFront(value, model.duration);
}

public void SetTextSynced(string text, float duration)
{
model.duration = duration;
model.text = text;
}
}
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;
using Normal.Realtime;

public class TextEvent : RealtimeComponent<TextEventModel>
{
protected override void OnRealtimeModelReplaced(TextEventModel previousModel, TextEventModel currentModel)
{
if (previousModel != null)
{
previousModel.textDidChange -= TextDidChange;
}

if (currentModel != null)
{
currentModel.textDidChange += TextDidChange;
}
}

private void TextDidChange(TextEventModel model, string value)
{
Debug.Log("text: " + value); // this is not being called
UIManager.Instance.notificationFront(value, model.duration);
}

public void SetTextSynced(string text, float duration)
{
model.duration = duration;
model.text = text;
}
}
using UnityEngine;
using Normal.Realtime;
using Normal.Realtime.Serialization;

[RealtimeModel]
public partial class TextEventModel
{
[RealtimeProperty(1, true, true, false )] private string _text;
[RealtimeProperty(2, true )] private float _duration;
}
using UnityEngine;
using Normal.Realtime;
using Normal.Realtime.Serialization;

[RealtimeModel]
public partial class TextEventModel
{
[RealtimeProperty(1, true, true, false )] private string _text;
[RealtimeProperty(2, true )] private float _duration;
}
Mechabit
Mechabitβ€’7mo ago
you probably want to check the value on model replaced in case it's already set when you join
gubebra
gubebraOPβ€’7mo ago
Still not working. I'm changing the model value here a lot of times and no luck. Do you now which version of Nomcore has this feature?
Mechabit
Mechabitβ€’7mo ago
2.9.3
gubebra
gubebraOPβ€’7mo ago
Yeah I have version 2.10.4 Is that expected behaviour? Because the event is called for the person that changed the variable.
Mechabit
Mechabitβ€’7mo ago
no, it should call the event
gubebra
gubebraOPβ€’7mo ago
Should I file a bug then?
Mechabit
Mechabitβ€’7mo ago
could do, as an alternative you can add an int property that you increment when you want to fire an event
maxweisel
maxweiselβ€’7mo ago
did you make a new build for all clients after updating normcore and enabling this flag?
gubebra
gubebraOPβ€’7mo ago
Yes, I actually have 2 editors open with the project
maxweisel
maxweiselβ€’7mo ago
if you're able to make a repro in a blank project, I'd love to take a look
gubebra
gubebraOPβ€’7mo ago
I'll try @Max I managed to repro on a blank project, here's the video
gubebra
gubebraOPβ€’7mo ago
No description
gubebra
gubebraOPβ€’7mo ago
Here're the project files
maxweisel
maxweiselβ€’7mo ago
@NormalMark want to take a look at this when you get a sec?
NormalMark
NormalMarkβ€’7mo ago
Hey, thanks for putting this test project together! We identified the issue and we're working on a fix πŸ‘
gubebra
gubebraOPβ€’7mo ago
Great to hear thanks!
Ata
Ataβ€’3w ago
Hello, I know it's been a while since this chat was created, but I’m experiencing the exact same issue. Did you manage to find a solution for it? My clone can only trigger once, just like in the video above. @NormalMark @maxweisel
Utku
Utkuβ€’3w ago
Heyo, I can confirm that clients won't receive change events. This is a simple model that I used to check whether the generated code is wrong or not. In the generated code, the event fires for the owner, but not in the clients. I see that, Read function in the generated code there is still a check for "changed" to Fire or not the event. I think there shouldn't be a check for the PlayerID.
No description
No description
No description
maxweisel
maxweiselβ€’3w ago
which version of Normcore are you on? we fixed a bug around this recently
Ata
Ataβ€’3w ago
2.12.1
maxweisel
maxweiselβ€’3w ago
Will you try on the latest version?
Ata
Ataβ€’3w ago
It still not working
maxweisel
maxweiselβ€’3w ago
@NormalMark will you take a look?
NormalMark
NormalMarkβ€’3w ago
@Ata @Utku Hey, thanks for the detailed report. Yes there is indeed a bug that generates an unnecessary change check. Can you test if this build of Normcore works as expected? https://drive.google.com/file/d/1DNR69VYZ04jKBGwPAWfBjWVJm17pJb0T/view?usp=sharing
Ata
Ataβ€’3w ago
@NormalMark After integrating this version into the project, nothing had changed, it was the same as the previous version. However when I deleted the Library folder and reopened the project, it updated and worked flawlessly. Thank you for resolving the issue.
NormalMark
NormalMarkβ€’3w ago
Glad to hear it! We'll try to land this fix in our next release πŸ‘
Ata
Ataβ€’7d ago
@NormalMark Hello there πŸ‘‹ I updated the last version of Normcore. It's not working like NoEqualityTestFix version.
Ata
Ataβ€’7d ago
This is a zip file version screenshot
No description
Ata
Ataβ€’7d ago
This one is 12.13.2 version
No description
Ata
Ataβ€’7d ago
Maybe I did something wrong may I ask you to check it if it's possible?
maxweisel
maxweiselβ€’7d ago
I don’t believe it has landed yet in Normcore mainline
NormalMark
NormalMarkβ€’7d ago
Correct, we haven't released that fix yet but we're working on it

Did you find this page helpful?