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
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:
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:
----------------------<@366873530199179264> kapa.ai is still learning and improving, please let us know how it did by reacting below
@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?
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:
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:
----------------------<@366873530199179264> kapa.ai is still learning and improving, please let us know how it did by reacting below
@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?
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:
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:
----------------------<@366873530199179264> kapa.ai is still learning and improving, please let us know how it did by reacting below
@Normcore Assistant Follow up question. When I instantiated a TextMeshPro object with Realtime View component attached to it. The text disappears. Any idea why?
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:
----------------------<@366873530199179264> kapa.ai is still learning and improving, please let us know how it did by reacting below
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?
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
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.
show us a screenshot
will do.. just a sec
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
inspector of the textmesh object
@Mechabit
can't you just append the string onto that text box?
if you add \n to the end it'll start a new line
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
you only need the view on the object that contains the realtime component
is global chat doing the syncing?
globalchatsync is doing the syncing
show us the code
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
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
and the text is there but invisible or it's blank?
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.
I don't think you need the realtime transform
Oh I think it was mandatory
it's probably going to 0,0,0
Ok I will give it a try. Thanks for helping out! ❤️
OMG YES! You genius!!!!