New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a way to transition text in #9137
Add a way to transition text in #9137
Comments
You did mention RichTextEffect. CharFXTransform even contains So, a system for this already exists. What's the drawback of the current system? |
Elapsed time doesn't act like it says it does, though. It's not elapsed time per character, it's time elapsed for the entire label since the text was set. This is... a bit of a roadblock to having it done cleanly. |
Well, if you are controlling how fast the text appears, calculating time needed to reach a character shouldn't be a problem. |
If the text is displayed at a variable rate, however, that becomes a lot more difficult. With the current system you can only have certain properties at any given time. Precalculated timing doesn't work when, say, you have dialogue that can be advanced earlier than it would normally finish by the player hitting "continue", which is generally standard in games with dialogue these days. |
If it is something like this: GkAujnU.mp4Then it's possible to do it with scripts. It's not straightforward but doable.
@tool
class_name FlyRichTextEffect
extends RichTextEffect
var bbcode = "fly"
var data = {}
var delta:float = 0.0
var visible_characters:int = -1:
set(new_value):
visible_characters = new_value
# Clean up the data if we are showing less characters than before
if visible_characters < 0:
data.clear()
else:
for data_range in data.keys():
if data_range.x > visible_characters:
data.erase(data_range)
func _process_custom_fx(char_fx: CharFXTransform) -> bool:
if visible_characters < 0:
return true
var starting_x = float(char_fx.env.get('start', -10))
var speed = float(char_fx.env.get('speed', 50))
var range = char_fx.range
# get the char data, set the default data if not available
var char_data = data.get(range, {
"offset_x": starting_x,
"end": char_fx.transform,
"finished": false
})
var finished = char_data.get("finished", false)
# if not finished then update the offset_x until it reaches 0
# update the char_fx values with that
if not finished:
var offset_x = char_data.get('offset_x', starting_x)
offset_x = move_toward(offset_x, 0, delta * speed)
if offset_x >= 0:
offset_x = 0
char_data['finished'] = true
char_fx.offset.x = floor(offset_x)
char_fx.color.a = remap(offset_x, starting_x, 0, 0.0, 1.0)
char_data['offset_x'] = offset_x
# update the data dictionary
data[range] = char_data
return true
@tool
extends RichTextLabel
var fly_effect:FlyRichTextEffect
func _ready() -> void:
# Disable clip contents or the first glyph of each line will be clipped from the left
clip_contents = false
fly_effect = FlyRichTextEffect.new()
custom_effects.clear()
install_effect(fly_effect)
func _process(delta: float) -> void:
fly_effect.delta = delta
fly_effect.visible_characters = visible_characters You can get an idea on how to get whatever effect you are after. Basically, maintain a dictionary with glyph ranges as keys and the data you want to update as values. When changing the If you need more control with how the visible characters animate in and out don't use |
Ah, so it is actually possible with not too much code, it's just... awkward and very unintuitive. I think that adding a tutorial for this effect (or something like this) to the docs, as I'm sure many developers would love to know that this is something you can do, as well as how to do it. As @mrcdk seems to know how it works, I think that he could be a good candidate for writing this tutorial. However, if I could get some direction from some of the more experienced Docs users, I could attempt to write this myself. |
I edited the above comment to use GDScript syntax highlighting, in case users are to stumble over this proposal. |
I was looking to add the same feature for my game in a less hacky way, so I opened a pull request for a simple, built-in method. |
Describe the project you are working on
Several games with a large amount of dialogue.
Describe the problem or limitation you are having in your project
A key piece of polish in games with dialogue these days is text transitioning in, so that instead of a character simply appearing on a frame, it might, say, fade in and drop into position over 4 frames, making the text a lot cleaner.
As it stands, Godot has no way to do this without sacrificing large amounts of premade features, quality of life, or both.
Describe the feature / enhancement and how it helps to overcome the problem or limitation
In RichTextLabels, there should be a way to transition characters in more smoothly. This has previously been discussed in #7270 and #5880, however both were too narrow in their discussion to implement an effective solution.
In essence, the feature that is needed is a way to define a RichTextEffect that only activates once, when a character becomes visible. This would allow dialogue (and any other text that people want to cleanly appear) in a RichTextLabel to be much more polished, and on par with what's generally standard with polished games
these daysthis millenium.Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
The implementation under the hood is up for discussion as I am unsure of how this would best be implemented, but on the user side it would work approximately like this:
Just another BBcode effect.
If this enhancement will not be used often, can it be worked around with a few lines of script?
This enhancement would, I believe, be used very often once implemented.
While it can hypothetically be worked around with scripting, it would require a large amount of script, and you would always be losing access to the automatic word shaping, an easy-to-use label, or a number of other features that make the RichTextLabel excellent for dialogue.
Is there a reason why this should be core and not an add-on in the asset library?
This is core functionality of the RichTextLabel.
The text was updated successfully, but these errors were encountered: