Text Chat System

Hiya! I was just wondering if there is any documentation at all about how to make a text chat system in NormCore using custom models?
31 Replies
kapa.ai
kapa.ai9mo ago
Hi @Hippolicious || CardaStacks. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- While the provided knowledge sources do not directly cover the creation of a text chat system using Normcore, they do provide some relevant information on how to synchronize custom data using RealtimeModel, which could be used to create a text chat system. A RealtimeModel represents a collection of states to synchronize. Each field in the model is required to be a primitive type, designed to synchronize data that can be easily serialized and transmitted to other clients. For a text chat system, you might create a RealtimeModel that includes a string property for the message text and an integer or string property for the sender ID. Here's an example of what a simple chat message model might look like:
[RealtimeModel]
public partial class ChatMessageModel {
[RealtimeProperty(1, true)] private string _messageText;
[RealtimeProperty(2, true)] private string _senderID;
}
[RealtimeModel]
public partial class ChatMessageModel {
[RealtimeProperty(1, true)] private string _messageText;
[RealtimeProperty(2, true)] private string _senderID;
}
In this model, _messageText would hold the text of the chat message, and _senderID could hold some identifier for the sender of the message. You can find more information on how to use RealtimeModel in practice in the Synchronizing custom data (https://normcore.io/documentation/realtime/synchronizing-custom-data) guide. Please note that this is a simplified example and a real implementation would likely need to consider additional factors, such as handling multiple messages and updating the chat in real-time for all users. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai9mo ago
<@366873530199179264> kapa.ai is still learning and improving, please let us know how it did by reacting below
Hippolicious || CardaStacks
@Normcore Assistant As it is not possible to instantiate objects as a child to a parent object in Normcore. How would you instantiate a TextMeshPro object?
kapa.ai
kapa.ai9mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- While it's true that Normcore does not support reparenting of objects with RealtimeView or RealtimeComponent, it doesn't prevent you from instantiating objects as children of other objects. The limitation is that the parent-child relationship will not be synchronized across the network. To instantiate a TextMeshPro object, you would typically do so in Unity as you would with any other GameObject. However, if you want to synchronize properties of the TextMeshPro object across the network, you would need to create a custom RealtimeModel that includes a field for each property of the TextMeshPro object that you want to synchronize. Here's an example of what a model for a TextMeshPro object might look like:
[RealtimeModel]
public partial class TextMeshProModel {
[RealtimeProperty(1, true)] private string _text;
[RealtimeProperty(2, true)] private Color _color;
// Add more properties as needed...
}
[RealtimeModel]
public partial class TextMeshProModel {
[RealtimeProperty(1, true)] private string _text;
[RealtimeProperty(2, true)] private Color _color;
// Add more properties as needed...
}
In this model, _text would hold the text of the TextMeshPro object, and _color could hold the color of the text. Once you have your model, you can create a RealtimeComponent subclass that uses your model and updates the TextMeshPro object accordingly. You can find more information on how to do this in the Synchronizing custom data (https://normcore.io/documentation/realtime/synchronizing-custom-data) guide. Please note that this is a simplified example and a real implementation would likely need to consider additional factors, such as handling updates to the TextMeshPro object in real-time for all users. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai9mo ago
<@366873530199179264> kapa.ai is still learning and improving, please let us know how it did by reacting below
Hippolicious || CardaStacks
@Normcore Assistant Ah right so I can Instantiate the text mesh pro objects at runtime but to have them synchronised across the network I need to use a custom model as well?
kapa.ai
kapa.ai9mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Yes, that's correct. In Normcore, you can instantiate any GameObject, including TextMeshPro objects, at runtime in Unity as you normally would. However, if you want to synchronize the state of these objects across the network, you would need to use a custom RealtimeModel. A RealtimeModel in Normcore represents a collection of states to synchronize. Each field in the model should be a primitive type (int, float, string, etc.) that can be easily serialized and transmitted to other clients. For a TextMeshPro object, you might create a RealtimeModel that includes a string property for the text content and other properties for any other attributes you want to sync (like color, font size, etc.). Here's an example of what a model for a TextMeshPro object might look like:
[RealtimeModel]
public partial class TextMeshProModel {
[RealtimeProperty(1, true)] private string _text;
[RealtimeProperty(2, true)] private Color _color;
// Add more properties as needed...
}
[RealtimeModel]
public partial class TextMeshProModel {
[RealtimeProperty(1, true)] private string _text;
[RealtimeProperty(2, true)] private Color _color;
// Add more properties as needed...
}
In this model, _text would hold the text of the TextMeshPro object, and _color could hold the color of the text. Once you have your model, you can create a RealtimeComponent subclass that uses your model and updates the TextMeshPro object accordingly. You can find more information on how to do this in the Synchronizing custom data (https://normcore.io/documentation/realtime/synchronizing-custom-data) guide. Please note that this is a simplified example and a real implementation would likely need to consider additional factors, such as handling updates to the TextMeshPro object in real-time for all users. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai9mo ago
<@366873530199179264> kapa.ai is still learning and improving, please let us know how it did by reacting below
Hippolicious || CardaStacks
@Normcore Assistant Follow up question. When I instantiated a TextMeshPro object with Realtime View component attached to it. The text disappears. Any idea why?
kapa.ai
kapa.ai9mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- The issue you're experiencing could be due to a few reasons. Here are some possibilities based on the provided knowledge sources: 1. RealtimeComponent's model remains null: The model is set by Realtime when you connect to the room. This will only fail if Realtime doesn't receive a reference to the RealtimeComponent. This can happen if the model was instantiated with Unity’s Instantiate API (Instantiate() or GameObject.Instantiate()) instead of Normcore’s Realtime.Instantiate(). If you're passing a prefab reference instead of a prefab string, then you're using the wrong one. Make sure to call Realtime.Instantiate(prefabName). Also, ensure that the model setter has been correctly implemented. Source (https://normcore.io/documentation/realtime/common-questions#why-would-a-realtimecomponents-model-remain-null) 2. RealtimeView doesn't have a model yet: If you’re dealing with a prefab, all views and components are initialized with their models. They will be ready to work with by the time Start() is called on any script on the prefab. Awake() must be called by Unity before Normcore can initialize any components on the game object. If you’re dealing with a RealtimeView that exists in a scene file, you’ll need to wait until realtime.connected == true, or the didConnectToRoom event has fired. Source (https://normcore.io/documentation/realtime/common-questions#why-do-i-get-the-error-this-view-doesnt-have-a-model-yet-wait-until-the-model-is-present-before-interacting-with-the-ownership-when-interacting-with-realtimeview) 3. Custom RealtimeComponent isn't syncing: You might have added your custom component to a game object before it was converted to a RealtimeComponent subclass. To verify this, look at the RealtimeView's list of components and make sure you see your custom component in the list. If you don't see it, or a RealtimeView has not been created for you automatically, try removing the component and re-adding it to your game object. Source (https://normcore.io/documentation/realtime/synchronizing-custom-data#my-custom-realtimecomponent-isnt-syncing-and-onrealtimemodelreplaced-doesnt-get-called) Please check these points and see if they help resolve your issue. If not, you might need to look into more specific documentation or reach out to the Normcore support for further assistance. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai9mo ago
<@366873530199179264> kapa.ai is still learning and improving, please let us know how it did by reacting below
Hippolicious || CardaStacks
Alright so it sounds like the model should solve all my problems.. let's give it a try Ok so according to kapa it should be working with a model, but I still have the text disappearing on me. Anyone has an idea how to fix it?
Mechabit
Mechabit9mo ago
do you mean the string is set but it's invisible? the reason for that is textmeshpro objects only render when they are children of a canvas you'll need to reparent the object after realtime instantiating
Hippolicious || CardaStacks
So I rewrote my code so I don't need to instantiate the TextMeshPro objects I just change the text within. When I don't have the Realtime Transform and View components added to the TextMeshPro objects it works.. when I add these components the text changes but is not visible on sceen.. I also made a custom model but that did not change a thing.
Mechabit
Mechabit9mo ago
show us a screenshot
Hippolicious || CardaStacks
will do.. just a sec
Hippolicious || CardaStacks
on the right you can see in the list I have added 2 messages..(by the way they are visible for one frame when pressing enter). I will add another screenshot so you can see how the text objects are made. Only thing I can think of now what it could be is that I am calling the sync model from the Game Manager instead of the text objects. I am calling it from the Game Manager as it is a singleton and will be persistent within scenes
No description
Hippolicious || CardaStacks
inspector of the textmesh object
No description
Hippolicious || CardaStacks
@Mechabit
Mechabit
Mechabit9mo ago
can't you just append the string onto that text box? if you add \n to the end it'll start a new line
Hippolicious || CardaStacks
I could, but I still need a realtime view on that textbox to get it synced right? And right now if I add that to the textObject , the textObject does not show up (or only briefly 1 frame) I mean the text within the object
Mechabit
Mechabit9mo ago
you only need the view on the object that contains the realtime component is global chat doing the syncing?
Hippolicious || CardaStacks
globalchatsync is doing the syncing
Mechabit
Mechabit9mo ago
show us the code
Hippolicious || CardaStacks
using System.Collections; using System.Collections.Generic; using UnityEngine; using TMPro; using Normal.Realtime; public class GlobalChatSync : RealtimeComponent<GlobalChatSyncModel> { private TMPro.TMP_Text chatText; private string _text;

private void Awake() { chatText = GetComponent<TMPro.TMP_Text>(); } protected override void OnRealtimeModelReplaced(GlobalChatSyncModel previousModel, GlobalChatSyncModel currentModel) { if (previousModel != null) { // Unregister from events previousModel.textDidChange -= TextDidChange; } if (currentModel != null) {
if (currentModel.isFreshModel) currentModel.text = chatText.text;
UpdateChatText();
currentModel.textDidChange += TextDidChange; } } private void TextDidChange(GlobalChatSyncModel model, string text) {
UpdateChatText(); } private void UpdateChatText() {


chatText.text = model.text; } public void SetText(string text) {
model.text = text; } } Sorry trying to get it to show up as code
Mechabit
Mechabit9mo ago
and the text is there but invisible or it's blank?
Hippolicious || CardaStacks
it shows up briefly for one frame... it is not blank.. it is there.. just not visible... you can also see it briefly when changing screen size in the editor... when you drag it.. is shows up flickering.. so it seems like it just updates once and does not persist.
Mechabit
Mechabit9mo ago
I don't think you need the realtime transform
Hippolicious || CardaStacks
Oh I think it was mandatory
Mechabit
Mechabit9mo ago
it's probably going to 0,0,0
Hippolicious || CardaStacks
Ok I will give it a try. Thanks for helping out! ❤️ OMG YES! You genius!!!!