I'm making a game on Godot in GDScript. I've got "abilities" in my game, a lot of them, really a lot of them. I might end up putting their description in XMLs or something else and even the rest of their info on it, and they might be "keywords" to simplify some explanations or recurrent mechanics.
So the question is: Can you detect mouseover (or other mouse interactions too) over specifics texts/words in a RichTextLabel, maybe thanks to some BBCode? Or maybe as said before there some text node more practical (even if I doubt it)?
From what I've seen, the RichTextLabel is the only to support text modifications and just "text difference" from the rest of the node, so might be the most able to, even if maybe very far, cuz of his ability to handle BBCode, but if what I'm thinking right now is the only solutions...
That would be to detect where certain BBCode balises in (X,Y) coordinates to place a "mouseover detect box" on those keywords, meaning you need to get (X,Y) coordinates of words in a paragraph, which isn't easily handled neither, you would need to calculate size of each character to calculate the position (X,Y) of a simple word... So yeah sound astoundingly hard to do.
Using
RichTextLabelis the easier approach here.As you know, it works with BBCode. Now, there are to ways to populate it:
You can set the
textproperty withbbcode_enabledenabled and it will parse it. See BBCode in RichTextLabel.For example, this will be "hello" written in red:
If you don't want to set it, but to append it, it is more efficient to use
append_text(this way Godot does not have to parse the whole text, but only the new part):Or you can do it by token...
Setting the BBCode by tokens works like an stack machine. You push (open) tags, append text, and pop (close) tags.
For example, this will be "hello" written in red:
Note: The
clearmethod does nor clear the text, instead it pops (closes) all currently pushed (open) tags.Now, there is a particular tag that will allow you to do what you want.
textuse"[url=something]text[/url]".push_meta("something").This will kind of create an "hyperlink". More precisely, it makes an item indented to be interacted with, inside of which text will be formatted - by default - similar to an hyperlink in a browser.
You, of course, are in control of the formatting. You might want to set
meta_underlinedtofalseto disable the default underline.What we are interested is the interactive part. While the tag does nothing by default, that is the point: we will define what it does. To do that, we need to handle some signals from the
RichTextLabel:meta_hover_started: When the mouse pointer begins hovering over the contents of one of the "hyperlink"s.meta_hover_ended: When the mouse pointer stops hovering over the contents of one of the "hyperlink"s.meta_clicked: When the use clicks one of the "hyperlink"s.And how do you know which "hyperlink"?
Well, these signals pass a value (
"something"in the examples above), which comes from the tag:push_metayou pass the value you want from the signals as an argument.Here
push_metahas an advantage over using text: the "url" attribute will only ever be anString, but the parameter ofpush_metais a Variant, you can pass anything there, including a reference to anObject, or aDictionarywith multiple values.The methods you connect to those signals would look something like this:
Refer to Using Signals to see how to make the connection.