Skip to content
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

Implement visible characters enter/exit FX in RichTextLabel #91749

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

jordigcs
Copy link
Contributor

@jordigcs jordigcs commented May 9, 2024

Resolves godotengine/godot-proposals#9137

Adds visibility_transition property to RichTextLabel, which takes a RichTextTransition resource.
This resource functions similarly to RichTextEffect, but instead of _process_custom_fx, there are 2 separate funcs for enter or exit fx.

Example

@tool
extends RichTextTransition

@export var speed:float = 2.5;

func _process_enter_fx(char_fx: CharFXTransform) -> bool:
	char_fx.color.a = lerp(0.0, 1.0, char_fx.elapsed_time * speed);
	char_fx.offset.y = lerp(-15.0, 0.0, char_fx.elapsed_time * speed);
	return char_fx.color.a >= 1;

func _process_exit_fx(char_fx: CharFXTransform) -> bool:
	char_fx.color.a = lerp(1.0, 0.0, char_fx.elapsed_time * speed);
	char_fx.offset.y = lerp(0.0, 15.0, char_fx.elapsed_time * speed);
	return char_fx.color.a <= 0;

text-transitions

Implementation Details

When a visibility_transition is set, making changes to visible_characters or visible_ratio will call _update_characters_to_transition, which will calculate the characters removed or added, and map a CharacterToTransition struct to the character. The CharacterToTransition struct contains data on if the character is entering or exiting, along with the transition's time elapsed. Before FX is processed, the RichTextLabel will check if the character currently being drawn is in the characters_to_transition map, and use the CharacterToTransition struct to call either _process_enter_fx or _process_exit_fx on the assigned RichTextTransition. If either of these methods return true, the character is done transitioning, and removed from the "to transition" map. Due to the nature of VisibleCharactersBehaviour::CHARS_BEFORE_SHAPING, having a RichTextTransition assigned restricts the visible character clipping behaviour to after shaping, to allow for exit fx.

@jordigcs jordigcs requested review from a team as code owners May 9, 2024 07:49
@jordigcs jordigcs force-pushed the rich-text-transition branch 2 times, most recently from 0063849 to 1313b79 Compare May 9, 2024 07:54
@jordigcs
Copy link
Contributor Author

jordigcs commented May 9, 2024

Here's a showcase of the feature with large amounts of text. For performance, the RichTextTransition will stop applying transitions when there is a large jump (>20 chars) in the amount of visible text.
long_text

Copy link
Member

@bruvzg bruvzg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will only work with "Characters After Shaping" mode, since it's assuming that visible range is character indices, but in other modes these are glyph indices (and should track processed_glyphs_step instead of character index).

Screen.Recording.2024-05-09.at.11.34.51.mov

@IntangibleMatter
Copy link

IntangibleMatter commented May 9, 2024

Here's a showcase of the feature with large amounts of text. For performance, the RichTextTransition will stop applying transitions when there is a large jump (>20 chars) in the amount of visible text.

While this is a good plan (when I attempted this I didn't cap it, and it got... very bad), I do think that setting a hard cap doesn't make a ton of sense. A better option might be to add this as a variable to the class (such as max_transition_characters).

(Though if it has to be a hardcoded cap, make it a power of 2. This is a programming thing after all :p)

<return type="bool" />
<param index="0" name="char_fx" type="CharFXTransform" />
<description>
Override this method to animate new characters shown when [member RichTextLabel.visible_characters] increases. Modified properties in [param char_fx] will be applied until this method returns [code]true[/code]. Return [code]true[/code] when the enter fx has finished.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that it makes more sense to return false when finished, to better match the way it's done in RichTextEffect. Instead of treating it as done = true treat it as processing effect = false. This means less problems when converting from richtexteffect. Same goes for _process_exit_effects.

@RedMser
Copy link
Contributor

RedMser commented May 9, 2024

This PR might help towards fixing godotengine/godot-proposals#6286 (by allowing detecting on when exactly a specific character got revealed)

A better option might be to add this as a variable to the class (such as max_transition_characters).

Agreed on this point, for a use-case like this it would be important to run the transition for every character.

Copy link
Contributor

@RedMser RedMser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to what I've done in #66600, it would be nice to create a GDScript template for RichTextTransition as well.

doc/classes/RichTextTransition.xml Show resolved Hide resolved
doc/classes/RichTextLabel.xml Show resolved Hide resolved
scene/gui/rich_text_label.cpp Outdated Show resolved Hide resolved
@jordigcs
Copy link
Contributor Author

jordigcs commented May 11, 2024

Force pushing the branch closed the PR for some reason? Unsure why that happened.
I've fixed typos. Working on adding support for the Glyph clipping modes. I will mark this as draft for now.

@jordigcs jordigcs marked this pull request as draft May 11, 2024 01:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a way to transition text in
5 participants