0 votes

I am trying to setup a dialog system where some words and hints are colored to emphasize them, like so:

An example of what I'm trying to accomplish

I've noticed that Godot has BBCode for the RichTextLabel node, but I've not figured out how to integrate it with the system I've set up. For the purpose of this question, I'll provide the most basic code of what I'm working with:

extends RichTextLabel




var NPC_TEST = []
func SET_NPC_TEST():
    NPC_TEST.push_back("<NPC NAME>")
    NPC_TEST.push_back("Hello! I am a NPC, and this is the color RED.")
    pass



var TIMER = Timer.new()
var WAIT_TIME = 0.05




var LINE = 0
var LINE_ARRAY = []




func _ready():
    TIMER_START()
    READY_NPC()
    START_DIALOG()
    pass




func READY_NPC():
    SET_NPC_TEST()
    pass




func TIMER_START():
    TIMER.connect("timeout", self, "TIMER_TIMEOUT_FUNCTION")
    TIMER.set_wait_time(WAIT_TIME)
    add_child(TIMER)
    TIMER.start()
    pass




func TIMER_TIMEOUT_FUNCTION():
    if LINE_ARRAY.size() > 0:
        self.add_text(LINE_ARRAY.pop_front())
        pass
    pass




func START_DIALOG():
    if LINE < NPC_TEST.size():
        LINE += 1
        LINE_ARRAY = []
        for i in NPC_TEST[LINE]:
            LINE_ARRAY.append(i)
            pass
        pass
    pass

Note: I know "pass" does not do anything, it is just a habit of mine.

Anyway I hope my setup isn't too complicated, but lets take a gander at this line:

NPC_TEST.push_back("Hello! I am a NPC, and this is the color RED.")

I would like the word "RED" to be... well, red.

I know this doesn't work:

NPC_TEST.push_back("Hello! I am a NPC, and this is the color [color=red]RED[/color].")

Any tips and tricks to get around this would be greatly appreciated!

asked Sep 3, 2019 in Engine by Melvin (19 points)

2 Answers

0 votes
Best answer

So I have figured it out...
Using the woes from someone else's post (here), I now know the existence of set_visible_characters.

I don't quite understand it fully, but here is the working code:

extends RichTextLabel




var NPC_TEST = []
func SET_NPC_TEST():
    NPC_TEST.push_back("<NPC NAME>")
    NPC_TEST.push_back("Hello! I am a NPC, and this is the color [color=red]RED[/color].")
    pass



var TIMER = Timer.new()
var WAIT_TIME = 0.05




var LINE = 0
var LINE_ARRAY = []




func _ready():
    TIMER_START()
    READY_NPC()
    START_DIALOG()
    self.bbcode_enabled = true
    pass




func READY_NPC():
    SET_NPC_TEST()
    pass




func TIMER_START():
    TIMER.connect("timeout", self, "TIMER_TIMEOUT_FUNCTION")
    TIMER.set_wait_time(WAIT_TIME)
    add_child(TIMER)
    TIMER.start()
    pass




func TIMER_TIMEOUT_FUNCTION():
    if LINE_ARRAY.size() > 0:
        #self.add_text(LINE_ARRAY.pop_front())
        self.bbcode_text = NPC_TEST[1]
        self.set_visible_characters(get_visible_characters()+1)
        pass
    pass




func START_DIALOG():
    if LINE < NPC_TEST.size():
        LINE += 1
        LINE_ARRAY = []
        for i in NPC_TEST[LINE]:
            LINE_ARRAY.append(i)
            pass
        pass
    pass
answered Sep 3, 2019 by Melvin (19 points)
selected Sep 3, 2019 by Melvin
0 votes

Using bbcode_text instead of text seems to work, there are some open github isses but this could probably be a new one about clearing up the naming a bit.

answered Sep 3, 2019 by flurick (886 points)

Thank you for even taking the time, but I should probably mention that my situation doesn't use RichTextLabel.text or RichTextLabel.set_text(). I am using add_text() as it appears to be the only thing I can use to simulate the *typing* effect I'm after. I have used RichTextLabel.bbcode_text but it behaves in much the same way as text and set_text(). Allow me to briefly explain what the code is doing:

It basically takes the string from the array NPC_TEST:

NPC_TEST = ["Hello! I am a NPC, and this is the color RED."]

Passes it to another array LINE_ARRAY, chopping it up so that it looks like this:

LINE_ARRAY = ["H", "e", "l", "l", "o", "!", " ", "I", " ", "a", "m", " ", "a", " ", "N", "P", "C", ",", "a", "n", "d", " ", "t", "h", "i", "s", " ", "i", "s", " ", "t", "h", "e", " ", "c", "o", "l", "o", "r", " ", "R", "E", "D", "."]

Then, using a Timer, prints the letters from LINE_ARRAY, one-by-one, on the RichTextLabel using add_text(). Simulating the aforementioned *typing* effect:

RichTextLabel.add_text(LINE_ARRAY.pop_front())

Perhaps what I'm doing here makes bbcoding impossible, but hopefully now you can see the dilemma I'm in.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.