generated from krampus/template-godot4
Advanced typewritery
This commit is contained in:
parent
37257dc3fd
commit
c536eff1db
|
@ -5,14 +5,18 @@ extends RichTextEffect
|
||||||
## Tag params:
|
## Tag params:
|
||||||
## - speed - Speed at which text is displayed, in characters per second.
|
## - speed - Speed at which text is displayed, in characters per second.
|
||||||
## - delay - Delay before displaying first character, in seconds.
|
## - delay - Delay before displaying first character, in seconds.
|
||||||
|
## - factor - Transition animation timescale factor.
|
||||||
|
|
||||||
signal typing
|
signal typing
|
||||||
signal on_frame_process_start
|
|
||||||
|
@export var scale_curve: Curve
|
||||||
|
@export var translation_curve: CurveXYZTexture
|
||||||
|
|
||||||
# To use this effect:
|
# To use this effect:
|
||||||
# - Enable BBCode on a RichTextLabel.
|
# - Enable BBCode on a RichTextLabel.
|
||||||
# - Instead of instantiating this effect directly, use a `TypewriterLabel` node.
|
# - 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 bbcode: String = "type"
|
||||||
|
|
||||||
var _force_visible := false
|
var _force_visible := false
|
||||||
|
@ -27,10 +31,40 @@ func _process_custom_fx(char_fx: CharFXTransform) -> bool:
|
||||||
if not _force_visible:
|
if not _force_visible:
|
||||||
var speed: float = char_fx.env.get("speed", Game.settings.default_text_speed)
|
var speed: float = char_fx.env.get("speed", Game.settings.default_text_speed)
|
||||||
var delay: float = char_fx.env.get("delay", 0.0)
|
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()
|
typing.emit()
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -11,15 +11,28 @@ signal typing_finished
|
||||||
## Useful for advancing skippable dialogue boxes.
|
## Useful for advancing skippable dialogue boxes.
|
||||||
signal force_visible
|
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 _finished: bool = true
|
||||||
var _typing: bool = false
|
var _typing: bool = false
|
||||||
|
|
||||||
|
@onready var _current_text: String = text
|
||||||
|
|
||||||
func _init() -> void:
|
|
||||||
|
func _ready() -> void:
|
||||||
bbcode_enabled = true
|
bbcode_enabled = true
|
||||||
var effect := TypewriterEffect.new(force_visible)
|
var effect := TypewriterEffect.new(force_visible)
|
||||||
|
effect.scale_curve = scale_curve
|
||||||
|
effect.translation_curve = translation_curve
|
||||||
effect.typing.connect(_on_typing)
|
effect.typing.connect(_on_typing)
|
||||||
install_effect(effect)
|
install_effect(effect)
|
||||||
|
if text:
|
||||||
|
_finished = false
|
||||||
|
|
||||||
|
|
||||||
## Is the typewriter effect finished?
|
## Is the typewriter effect finished?
|
||||||
|
@ -33,12 +46,17 @@ func reset() -> void:
|
||||||
_finished = false
|
_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.
|
## 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()
|
reset()
|
||||||
clear()
|
clear()
|
||||||
append_text(text)
|
append_text(new_text)
|
||||||
|
_current_text = new_text
|
||||||
|
|
||||||
|
|
||||||
func _process(_delta: float) -> void:
|
func _process(_delta: float) -> void:
|
||||||
|
|
Loading…
Reference in New Issue