I am currently working on a Unity project where I am creating a WhatsApp-style chat application. I have implemented a feature where users can scroll up to see previous messages. However, I am encountering a peculiar issue with the display of newly instantiated messages.
Here's a brief overview of the problem:
Each time a new message arrives, I instantiate a new TextBox within the TextBoxContainer to display it.
After instantiating the new TextBox, I programmatically scroll to the bottom to ensure the latest message is visible.
Strangely, the newly instantiated message does not appear at the bottom of the scrollable area, even though the scrolling function is correctly executed.
A workaround I discovered is to temporarily set the active state of the TextBoxContainers to false and then set it back to true. This somehow resolves the issue, and the new message is displayed correctly at the bottom after scrolling.
Here is a video about the problem
I am puzzled by this behavior, and I would appreciate any insights or suggestions on how to address this issue without resorting to the workaround. Below is a simplified version of the code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using Subtegral.DialogueSystem.DataContainers;
namespace Subtegral.DialogueSystem.Runtime
{
public class DialogueParser : MonoBehaviour
{
[SerializeField] private DialogueContainer dialogue;
[SerializeField] private Button choicePrefab;
[SerializeField] private Transform buttonContainer;
[SerializeField] private GameObject textBoxPrefab;
[SerializeField] private Transform textBoxContainer;
[SerializeField] private Transform textBoxContainer2;
private void Start()
{
var narrativeData = dialogue.NodeLinks.First(); //Entrypoint node
Debug.Log(dialogue.DialogueNodeData.First().DialogueText);
ProceedToNarrative(narrativeData.TargetNodeGUID);
}
private void ProceedToNarrative(string narrativeDataGUID)
{
var text = dialogue.DialogueNodeData.Find(x => x.NodeGUID == narrativeDataGUID).DialogueText;
var choices = dialogue.NodeLinks.Where(x => x.BaseNodeGUID == narrativeDataGUID);
GameObject instantiatedTextBox1 = Instantiate(textBoxPrefab, textBoxContainer);
instantiatedTextBox1.GetComponentInChildren<TextMeshProUGUI>().text = ProcessProperties(text);
var buttons = buttonContainer.GetComponentsInChildren<Button>();
for (int i = 0; i < buttons.Length; i++)
{
Destroy(buttons[i].gameObject);
}
foreach (var choice in choices)
{
var button = Instantiate(choicePrefab, buttonContainer);
button.GetComponentInChildren<Text>().text = ProcessProperties(choice.PortName);
button.onClick.AddListener(() => ProceedToNarrative(choice.TargetNodeGUID));
button.onClick.AddListener(() => deneme(button));
}
}
private string ProcessProperties(string text)
{
foreach (var exposedProperty in dialogue.ExposedProperties)
{
text = text.Replace($"[{exposedProperty.PropertyName}]", exposedProperty.PropertyValue);
}
return text;
}
private void deneme(Button button)
{
Text buttontext = button.GetComponentInChildren<Text>();
GameObject instantiatedTextBox2 = Instantiate(textBoxPrefab, textBoxContainer2);
instantiatedTextBox2.GetComponentInChildren<TextMeshProUGUI>().text = buttontext.text;
}
}
}