VaelisDocs
v1.0.0
Scripting · v1.0.0

Tween API

Animate numeric properties smoothly with tween(), choose from 33 easing curves, and stop animations with cancelTween().

View as Markdownllms.txt

#Overview

tween(target, properties, duration, easing, onComplete) smoothly moves one or more numeric properties from their current value to a target value over a number of game seconds. It is a global function, available in every script with no import. It returns a numeric id you can pass to cancelTween(id).

ArgumentTypeMeaning
targetobjectAn entity context (this, or the result of findFirst() etc.) or a scripting component object such as this.sprite, this.light or this.camera.
propertiesobjectMap of property name to end value, for example { x: 420, y: 180 }. Only finite numbers are accepted as end values.
durationnumberLength in game seconds. 0 (or an invalid value) completes on the next tween update.
easingstringOptional. One of the 33 easing names. Empty or omitted means "linear".
onCompletefunctionOptional. Called once when the tween finishes, with this bound to the entity that started the tween.
js
function onStart() {
  // Move, spin and resize over 0.8 game seconds
  tween(this, { x: 420, y: 180, rotation: 90, scaleX: 1.2, scaleY: 1.2 }, 0.8, "easeOutCubic", function () {
    // "this" is still the entity that started the tween
    tween(this.sprite, { opacity: 0.25 }, 0.35, "easeInOutSine");
  });
}

#What can be tweened

A property is tweened only if it already exists on the target and currently holds a finite number. Properties that are missing, non-numeric (colours are hex strings, position and scale are objects) or non-finite are skipped.

TargetTypical tweenable properties
this (entity)x, y, rotation, scaleX, scaleY
this.spriteopacity
this.shapewidth, height, radius, opacity, outlineWidth
this.textfontSize, opacity
this.lightintensity, radius, angle, shadowStrength
this.audiovolume, pitch
this.camerazoom, offsetX, offsetY
this.strokePaththickness, opacity, textureOffset
scene.lightingambientDarkness, glowStrength

Any numeric member listed on a component's Script API table can be a tween target. Each tween writes through the normal script API, so setter rules (clamping, validation) still apply.

#Cancelling

js
var id = tween(this, { x: 700 }, 2, "easeOutBounce");
// later
var wasActive = cancelTween(id);   // true only if a tween with that id was still running

cancelTween() leaves the property at whatever value it had reached. onComplete is not called for a cancelled tween.

#Behavior and rules

  • Start tweens from lifecycle callbacks such as onStart(), onClick() or a collision handler. Calling tween() outside script execution logs [tween] warning and returns -1. Avoid creating a new tween every frame in onUpdate(); start one and let it run.
  • Game time. Tweens advance once per frame after onUpdate callbacks, using the scaled frame clock. time.scale speeds them up or slows them down, and scene.pause() freezes them.
  • Exact finish. When progress reaches 1 the property is set to the exact end value, so back/elastic overshoot never leaves a rounding error.
  • Several properties at once in one call share the same duration and easing.
  • Automatic cleanup. A tween ends silently if the entity that started it, or the entity it targets, is destroyed. Restarting or switching scenes clears all tweens.
  • Errors. If an easing function or a property setter throws, that tween is removed and the error is reported in the Console with the owning entity name. A completion callback that throws is reported as tween onComplete.
  • Return value. Invalid input (bad target, properties not an object, unknown easing, no numeric properties, non-function onComplete) returns -1 and logs a [tween] warning that says what to fix. An unknown easing name is never silently treated as linear.
  • Easing names are case-insensitive and ignore spaces, hyphens and underscores, so "EASE-OUT-QUAD" equals "easeOutQuad".
Tweening physics bodiesAssigning x or y on an entity that has a Dynamic or Kinematic Rigidbody2D teleports the body each frame. For moving physics objects use velocities or forces; use tween for transforms, opacity, UI, lights, cameras and Static or non-physics entities.

#Editor support

The Script Editor autocompletes tween and cancelTween, and offers the easing names inside the easing string (type tween(this, { x: 100 }, 1, "easeOut and the matching names appear). Both names are syntax-highlighted as engine globals.

#Easing catalogue

Every name below is a real engine easing. Each preview is drawn from the engine's own easing function: the horizontal axis is time (0 to 1) and the vertical axis is progress. The dashed lines mark the start value (bottom) and end value (top); curves that cross them overshoot on purpose. In starts slowly, Out ends slowly, InOut does both.

FamilyNames
Basiclinear, smoothstep, smootherstep
QuadeaseInQuad, easeOutQuad, easeInOutQuad
CubiceaseInCubic, easeOutCubic, easeInOutCubic
QuarteaseInQuart, easeOutQuart, easeInOutQuart
QuinteaseInQuint, easeOutQuint, easeInOutQuint
SineeaseInSine, easeOutSine, easeInOutSine
ExpoeaseInExpo, easeOutExpo, easeInOutExpo
CirceaseInCirc, easeOutCirc, easeInOutCirc
BackeaseInBack, easeOutBack, easeInOutBack
ElasticeaseInElastic, easeOutElastic, easeInOutElastic
BounceeaseInBounce, easeOutBounce, easeInOutBounce

#Basic

linear
smoothstep
smootherstep

#Quad

easeInQuad
easeOutQuad
easeInOutQuad

#Cubic

easeInCubic
easeOutCubic
easeInOutCubic

#Quart

easeInQuart
easeOutQuart
easeInOutQuart

#Quint

easeInQuint
easeOutQuint
easeInOutQuint

#Sine

easeInSine
easeOutSine
easeInOutSine

#Expo

easeInExpo
easeOutExpo
easeInOutExpo

#Circ

easeInCirc
easeOutCirc
easeInOutCirc

#Back

easeInBack
easeOutBack
easeInOutBack

#Elastic

easeInElastic
easeOutElastic
easeInOutElastic

#Bounce

easeInBounce
easeOutBounce
easeInOutBounce

#Recipes

#Fade out and destroy

js
function onClick() {
  tween(this.sprite, { opacity: 0 }, 0.4, "easeInQuad", function () {
    this.destroy();
  });
}

#Pop-in UI

js
function onStart() {
  this.scaleX = 0;
  this.scaleY = 0;
  tween(this, { scaleX: 1, scaleY: 1 }, 0.5, "easeOutBack");
}

#Light pulse that can be stopped

js
function onStart() {
  this._pulse = tween(this.light, { intensity: 2 }, 0.6, "easeInOutSine", function () {
    tween(this.light, { intensity: 0.5 }, 0.6, "easeInOutSine");
  });
}
function onDestroy() { cancelTween(this._pulse); }

#Slow-motion hit stop with a tween that ignores nothing

js
function onCollisionEnter(other) {
  time.scale = 0.2;                 // tweens and timers slow down too
  wait(0.3, function () { time.scale = 1; });
}