Animação por código
Uma track de posição e uma de cor escritas chave por chave no início, sem nenhum arquivo .anim. A linha do tempo abaixo mostra as mesmas chaves que o código inseriu.
O editor acima está rodando este projeto. Mude uma linha e ele recarrega.
Classes do Godot usadas
AnimationPlayerAnimationAnimationLibrary
O código
scripts/main.gd
extends Node
const LENGTH: float = 2.4
const RADIUS: float = 36.0
const TRACK_LEFT: float = 150.0
const TRACK_WIDTH: float = 980.0
const TRACK_Y: float = 620.0
const KEYS: Array = [
{time = 0.0, position = Vector2(430, 210), color = '#8da5f3'},
{time = 0.6, position = Vector2(960, 250), color = '#8eef97'},
{time = 1.2, position = Vector2(1010, 470), color = '#f3d48d'},
{time = 1.8, position = Vector2(490, 440), color = '#fc7f7f'},
{time = 2.4, position = Vector2(430, 210), color = '#8da5f3'},
]
var player: AnimationPlayer
var playhead: ColorRect
func _ready() -> void:
_add_background()
_add_label('Animation and AnimationLibrary built at runtime, no .anim file', Vector2(40, 40))
for key in KEYS:
var mark: Polygon2D = _make_circle(10.0, Color(key.color))
mark.position = key.position
add_child(mark)
var blob: Polygon2D = _make_circle(RADIUS, Color(KEYS[0].color))
blob.name = 'Blob'
blob.position = KEYS[0].position
add_child(blob)
var animation: Animation = Animation.new()
animation.length = LENGTH
animation.loop_mode = Animation.LOOP_LINEAR
var position_track: int = animation.add_track(Animation.TYPE_VALUE)
animation.track_set_path(position_track, 'Blob:position')
animation.track_set_interpolation_type(position_track, Animation.INTERPOLATION_CUBIC)
var color_track: int = animation.add_track(Animation.TYPE_VALUE)
animation.track_set_path(color_track, 'Blob:color')
for key in KEYS:
animation.track_insert_key(position_track, key.time, key.position)
animation.track_insert_key(color_track, key.time, Color(key.color))
var library: AnimationLibrary = AnimationLibrary.new()
library.add_animation('orbit', animation)
player = AnimationPlayer.new()
add_child(player)
player.add_animation_library('', library)
player.play('orbit')
_add_timeline()
print('the dots are the keyframe positions, the ticks are their times')
func _process(_delta: float) -> void:
var progress: float = player.current_animation_position / LENGTH
playhead.position.x = TRACK_LEFT + TRACK_WIDTH * progress
func _add_timeline() -> void:
var rail: ColorRect = ColorRect.new()
rail.color = Color('#2a2f3d')
rail.position = Vector2(TRACK_LEFT, TRACK_Y)
rail.size = Vector2(TRACK_WIDTH, 10)
add_child(rail)
for key in KEYS:
var tick: ColorRect = ColorRect.new()
tick.color = Color(key.color)
tick.size = Vector2(6, 34)
tick.position = Vector2(TRACK_LEFT + TRACK_WIDTH * key.time / LENGTH - 3.0, TRACK_Y - 12)
add_child(tick)
playhead = ColorRect.new()
playhead.color = Color('#ffffff')
playhead.size = Vector2(3, 56)
playhead.position = Vector2(TRACK_LEFT, TRACK_Y - 23)
add_child(playhead)
func _make_circle(radius: float, color: Color) -> Polygon2D:
var points: PackedVector2Array = PackedVector2Array()
for i in 32:
var angle: float = TAU * i / 32
points.append(Vector2(cos(angle), sin(angle)) * radius)
var circle: Polygon2D = Polygon2D.new()
circle.polygon = points
circle.color = color
return circle
func _add_background() -> void:
var background: ColorRect = ColorRect.new()
background.color = Color('#12141a')
add_child(background)
background.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
func _add_label(text: String, at: Vector2) -> void:
var label: Label = Label.new()
label.text = text
label.position = at
label.add_theme_color_override('font_color', Color('#999999'))
add_child(label)