Forum rules - please read before posting.

Advice re: keeping many speech strings on screen at once.

edited January 2022 in Technical Q&A

I use speech bubbles for regular gameplay, but now I'm making a desktop PC where the player can use message boards, chat on an instant messenger, etc. I was wondering whether there is a tried and tested method of displaying several chat messages in a single textmeshpro element? I'm asking because I imagine others might have tried to implement a chat system like the Kentucky Route Zero one, for example:

Those messages don't appear all at once - they are timed like a regular conversation, but the end result looks like a film script, which is basically what I'm looking for functionality-wise (except for the fact that KRZ has a typewriter effect, but this can be easily disabled with AC).

I have set up Unity UI in such a way that the textmeshpro element has a constant width and a vertical content size fitter. I created an empty child element under it so that it has a minimum height (about the same size as the KRZ speech box) even when the text component is empty. The text is top-left aligned, so first it will fill the box from top to bottom. When it reaches the bottom, the textmeshpro element resizes because of the content size fitter, but it does so upwards instead of downwards because of the way I anchored the element. The final touch is to use a mask to make the overflow at the top invisible.

I'm not entirely sure what the best way to populate the textmeshpro element with speech text is though.

Any advice?

Comments

  • You'll need to rely on a custom script that manages when text gets added, and when it gets removed.

    The starting point of this is to hook into the OnStartSpeech custom event, which is triggered whenever a character speaks. This event provides the character and speech text as parameters.

    A tutorial on this can be found here. The end result is that speech gets displayed in the console, but it can be adapted to instead add this text to a TextMeshProUGUI component. This wouldn't strictly need to involve AC's menu system - TMPro could be used independently here.

  • edited January 2022

    Thanks, Chris!

    If anyone else is looking for a similar solution, this is what I put together (you just need to add it to the UI object that contains the TMPro component):

    using UnityEngine;
    using AC;
    using TMPro;
    
    public class SpeechListener : MonoBehaviour
    {
    
        private string IMtext;
        private TextMeshProUGUI FullChat;
    
        void OnEnable() { EventManager.OnStartSpeech += GetSpeech; }
        void OnDisable() { EventManager.OnStartSpeech -= GetSpeech; }
    
        public void Awake()
        {
            FullChat = this.GetComponent<TMPro.TextMeshProUGUI>();          
        }
    
        void GetSpeech(AC.Char speakingCharacter, string speechText, int lineID)
        {
    
            if (speakingCharacter.GetName() == "Player Name")
                {
                IMtext = "<color=red>" + speakingCharacter.GetName() + ":</color> " + speechText + "\n\n";
            }
            else
            {
                IMtext = "<color=blue>" + speakingCharacter.GetName() + ":</color> " + speechText + "\n\n";
            }
    
            FullChat.text = FullChat.text + IMtext; 
    
        }
    
    }
    
  • Chris, something I've noticed: how do I empty the speech text string once the character is done speaking? "Retain subtitle text buffer once line has ended?" is unchecked, and "update if string is empty?" on the menu element doesn't seem to do anything.

    What I'm trying to accomplish:

    1. The player clicks on an invisible button on top of the textbox, which runs an ActionList and gives the player dialogue options [OK]
    2. Upon selecting a dialogue option, the speech is scrolled inside the textbox (as if the player were typing the response) because it is hooked to an AC menu label [type: dialogue line] [OK]
    3. On Stop Speech, the speech line is cleared from the textbox [FAIL] AND is appended to the chat text above [OK]

    I could try hiding/unhiding the TMPro panel where the "typing" occurs, but this might work better if I there was a way to simply flush the text once the speech was over?

    This is the script I've got so far:

    using UnityEngine;
    using AC;
    using TMPro;
    
    public class DesktopIM : MonoBehaviour
    {
        private string IMtext;
        private TextMeshProUGUI FullChat;
    
        void OnEnable() 
        { 
            EventManager.OnStartSpeech += GetSpeech;
            EventManager.OnStopSpeech += OnStopSpeech;
        }
        void OnDisable() 
        { 
            EventManager.OnStartSpeech -= GetSpeech;
            EventManager.OnStopSpeech -= OnStopSpeech;
        }   
    
        public void Awake()
        {
            FullChat = this.GetComponent<TMPro.TextMeshProUGUI>();      
        }
    
        void GetSpeech(AC.Char speakingCharacter, string speechText, int lineID)
        {
    
            if (speakingCharacter.GetName() == "Player Name")
                {
                IMtext = "\n\n<color=red>" + speakingCharacter.GetName() + ":</color> " + speechText;
            }
            else
            {
                IMtext = "\n\n<color=blue>" + speakingCharacter.GetName() + ":</color> " + speechText;
            }
    
        }
    
        private void OnStopSpeech(AC.Char character)
        {
    
            FullChat.text = FullChat.text + IMtext;
    
        }
    
    }
    
  • edited January 2022

    Actually, maybe I should consider hiding/unhiding the panel instead via code. I've just realised that the only way to filter the displayed lines by speaker is to set the entire menu's appear type to "when speech plays". Since the menu is the ENTIRE desktop, this is impossible in this case, but I really need to do it because I only want the player's lines to be "typed".

    I will attempt that.

    Edit: all sorted.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.