Advanced typewritery

This commit is contained in:
Rob Kelly 2024-12-10 15:02:48 -07:00
parent 37257dc3fd
commit c536eff1db
2 changed files with 60 additions and 8 deletions

View File

@ -5,14 +5,18 @@ extends RichTextEffect
## Tag params:
## - speed - Speed at which text is displayed, in characters per second.
## - delay - Delay before displaying first character, in seconds.
## - factor - Transition animation timescale factor.
signal typing
signal on_frame_process_start
@export var scale_curve: Curve
@export var translation_curve: CurveXYZTexture
# To use this effect:
# - Enable BBCode on a RichTextLabel.
# - Instead of instantiating this effect directly, use a `TypewriterLabel` node.
# - Use [type speed=10.0 delay=0.0]hello[/type] in text.
# - Animation curves are exported by `TypewriterLabel`.
# - Use [type speed=10.0 delay=0.0 factor=1.0]hello[/type] in text.
var bbcode: String = "type"
var _force_visible := false
@ -27,10 +31,40 @@ func _process_custom_fx(char_fx: CharFXTransform) -> bool:
if not _force_visible:
var speed: float = char_fx.env.get("speed", Game.settings.default_text_speed)
var delay: float = char_fx.env.get("delay", 0.0)
var factor: float = char_fx.env.get("factor", 1.0)
char_fx.visible = (char_fx.elapsed_time - delay) * speed >= char_fx.relative_index
var server := TextServerManager.get_primary_interface()
var glyph_size := server.font_get_glyph_size(char_fx.font, Vector2i.ONE, char_fx.glyph_index)
var pivot := glyph_size * Vector2(-1, 1)
if not char_fx.visible:
var rel_time := (
(speed * (char_fx.elapsed_time - delay) - char_fx.relative_index) / factor
)
var scale := Vector2.ONE
if scale_curve:
scale *= scale_curve.sample_baked(rel_time)
var translation := Vector2.ZERO
if translation_curve:
if translation_curve.curve_x:
translation.x = translation_curve.curve_x.sample_baked(rel_time)
if translation_curve.curve_y:
translation.y = translation_curve.curve_y.sample_baked(rel_time)
char_fx.transform = (
char_fx
. transform
. translated_local(-pivot)
. scaled_local(scale)
. translated_local(pivot)
. translated_local(translation)
)
char_fx.visible = rel_time > 0
if rel_time < 1:
typing.emit()
return true

View File

@ -11,15 +11,28 @@ signal typing_finished
## Useful for advancing skippable dialogue boxes.
signal force_visible
## Scale curve for animated typewriter character transition.
@export var scale_curve: Curve
## Translation curve for animated typewriter character transition.
## The Z curve will not be used.
@export var translation_curve: CurveXYZTexture
var _finished: bool = true
var _typing: bool = false
@onready var _current_text: String = text
func _init() -> void:
func _ready() -> void:
bbcode_enabled = true
var effect := TypewriterEffect.new(force_visible)
effect.scale_curve = scale_curve
effect.translation_curve = translation_curve
effect.typing.connect(_on_typing)
install_effect(effect)
if text:
_finished = false
## Is the typewriter effect finished?
@ -33,12 +46,17 @@ func reset() -> void:
_finished = false
## Clear the text box and set a new line of text.
## Restart the existing typing effect.
func restart() -> void:
display_text(_current_text)
## The `finished` signal will be emitted when the text is done displaying.
func display_text(text: String) -> void:
func display_text(new_text: String) -> void:
reset()
clear()
append_text(text)
append_text(new_text)
_current_text = new_text
func _process(_delta: float) -> void: