Animation par code
Une piste de position et une de couleur écrites clé par clé au démarrage, sans aucun fichier .anim. La timeline en dessous montre les mêmes clés que le code a insérées.
L'éditeur ci-dessus fait tourner ce projet. Changez une ligne et il se recharge.
Classes Godot utilisées
AnimationPlayerAnimationAnimationLibrary
Le code
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)