Animation - kuimoani/defold GitHub Wiki
Animation
Defoldλ μ€λΈμ νΈ μ»΄ν¬λνΈμ κ·Έλν½ μμ€λ‘ μ¬μ©ν μ μλ λ€μν μ’ λ₯μ μ λλ©μ΄μ μ μ§μν©λλ€.
Flip-book animation
νλ¦½λΆ μ λλ©μ΄μ μ μ°μμ μΌλ‘ νμλλ μΌλ ¨μ μ€νΈμ»· μ΄λ―Έμ§λ€λ‘ ꡬμ±λ©λλ€. μ΄ κΈ°μ μ μ ν΅μ μΈ μ μλλ©μ΄μ κ³Ό λ§€μ° λΉμ·ν©λλ€(http://en.wikipedia.org/wiki/Traditional_animation μ°Έκ³ ). μ΄ λ°©μμ κ°κ°μ νλ μμ κ°λ³μ μΌλ‘ μ‘°μνλ―λ‘ λ¬΄νν κ°λ₯μ±μ΄ μμ΅λλ€. νμ§λ§ νλ μ λ§λ€ κ³ μ ν μ΄λ―Έμ§λ‘ μ μ₯ν΄μΌ νλ―λ‘ λ©λͺ¨λ¦¬ 곡κ°μ΄ λ§μ΄ νμν μ μμ΅λλ€. λν μ λλ©μ΄μ μ λΆλλ½κ² νννλ €λ©΄ λ§€ μ΄λ§λ€ λνλλ μ΄λ―Έμ§μ μλ₯Ό λ리λλ° μμ‘΄ν΄μΌ νλ―λ‘ κ·Έλ§νΌ μμ λ λν μ¦κ°νκ² λ©λλ€. Defoldμ νλ¦½λΆ μ λλ©μ΄μ μ κ°λ³ μ΄λ―Έμ§λ₯Ό μνλΌμ€μ μΆκ°νμ¬ μ μ₯νκ±°λ λͺ¨λ νλ μμ΄ μνμ μΌλ‘ λ°°μΉλ νμΌ μμ€μ μ μ₯λ©λλ€.

Spine animation
μ€νμΈ μ λλ©μ΄μ μ 2D μ€μΌλ ν€ μ λλ©μ΄μ μ μ 곡ν©λλ€ (http://en.wikipedia.org/wiki/Skeletal_animation μ°Έκ³ ). μ΄λ μ»·μμ μ λλ©μ΄μ κ³Όλ κ·Όλ³Έμ μΌλ‘ λ€λ₯Έ κΈ°μ μ λλ€. μ»·μμ μ λλ©μ΄μ μμλ μ λλ©μ΄μ μ€λΈμ νΈμ κ°λ³ μ‘°κ°λ€(μλ₯Ό λ€μ΄ λͺΈμ²΄, λ, μ λ±)μ΄ κ° νλ μκ° κ°λ³μ μΌλ‘ μμ§μ λλ€. μ€νμΈ μ λλ©μ΄μ μ μλ‘ μ°κ²°λ λΌλ κ΅¬μ‘°λ‘ κ΅¬μ±λ 보μ΄μ§ μλ κ°μμ 골격μ λ§λλλ€. κ°λ³ μ΄λ―Έμ§λ₯Ό κ° λΌλμ λΆμ΄κ³ μ΄ κ³¨κ²©(skeleton) νΉμ λ¦(rig)μ μ λλ©μ΄μ μ²λ¦¬ ν μ μμ΅λλ€. Defoldλ μ€νμΈ JSON ν¬λ©§μΌλ‘ μ λλ©μ΄μ μ μμ±νκ±°λ μ΅μ€ν¬νΈ νλ κ²μ μ§μν©λλ€. μ€μΌλ ν€ μ λλ©μ΄μ μ μμ§μ΄ λ§€ νλ μλ§λ€ κ° λΌλμ μμΉλ₯Ό 보κ°(interpolate)ν΄ μ£ΌκΈ° λλ¬Έμ λ§€μ° λΆλλ½κ² μμ§μ λλ€.
μ€νμΈ λ°μ΄ν°λ₯Ό μ΄λ»κ² μν¬νΈ νλμ§ μμΈν λ³΄λ €λ©΄ Spine λ¬Έμλ₯Ό μ°Έκ³ λ°λλλ€.

3D skinned animation
3D λͺ¨λΈμ μ€μΌλ ν€ μ λλ©μ΄μ μ μ€νμΈ μ λλ©μ΄μ κ³Ό λΉμ·νμ§λ§ 2Dκ° μλλΌ 3Dλ‘ λμν©λλ€. 3D λͺ¨λΈμ λ³λμ ννΈλ‘ μλ¦¬μ§ μκ³ μ»·μμ μ λλ©μ΄μ μ²λΌ λΌλλ‘ λ¬Άμ λλ€. λμ μ΄ λΌλλ€μ λͺ¨λΈμ λ²ν μ€(vertex)μ λ³ν(deformation)μ μ μ©ν μ μμΌλ©°, λΌλκ° λ²ν μ€μ μν₯μ λ―ΈμΉλ μ λλ₯Ό μ μ΄ν μ μμ΅λλ€.
3D λ°μ΄ν°λ₯Ό μ λλ©μ΄μ λͺ¨λΈλ‘ μν¬νΈ νλ μμΈν λ°©λ²μ 3D graphics λ¬Έμλ₯Ό μ°Έκ³ λ°λλλ€.

Property animation
μ«μλ‘ λ λͺ¨λ μμ±(μ«μ, vector3, vector4, μΏΌν°λμ¨(quaterion))μ λ΄μ₯λ μ λλ©μ΄μ μμ€ν μμ go.animate() ν¨μλ₯Ό μ¬μ©ν΄μ μ λλ©μ΄μ ν¨κ³Όλ₯Ό μ€ μ μμΌλ©° μ ν ν νλ μ΄λ°± λͺ¨λ(playback mode)λ μ΄μ§(easing) ν¨μμ λ°λΌ μμ§μ΄ μλμ μΌλ‘ μμ±κ°λ€μ νΈμλ(tween) ν©λλ€. λν μ΄μ§ ν¨μλ₯Ό 컀μ€ν νκ² λ³κ²½ν μλ μμ΅λλ€.

Playing flip-book animations
μ€νλΌμ΄νΈμ GUI λ°μ€ λ Έλλ νλ¦½λΆ μ λλ©μ΄μ μ μ¬μν μ μμΌλ©° λ°νμμ μ΄λ₯Ό μ μ΄ν μ μμ΅λλ€.
Sprites
μ€νλΌμ΄νΈλ₯Ό λ°νμμ μ λλ©μ΄μ μ νκΈ° μν΄μλ play_animation λ©μΈμ§λ₯Ό ν μ€μ³λ₯Ό μ λλ©μ΄μ νκΈΈ μνλ μ€νλΌμ΄νΈ μ»΄ν¬λνΈμ 보λ΄μΌ ν©λλ€. μ λλ©μ΄μ μ΄ νλ μ΄λ₯Ό λλ΄μ λ§μ, μμ§μ play_animation λ©μΈμ§λ₯Ό 보λλ μ€ν¬λ¦½νΈλ‘ animation_done λ©μΈμ§λ₯Ό λλ € μ€λλ€.
GUI box nodes
GUI λ°μ€ λ Έλλ₯Ό λ°νμμ μ λλ©μ΄μ μ νκΈ° μν΄μλ gui.play_flipbook() ν¨μλ₯Ό μ¬μ©ν΄μΌ ν©λλ€. μλ μμ λ₯Ό μ΄ν΄λ³΄κΈ° λ°λλλ€.
Sprite example
λΉμ μ κ²μμ "dodge"λΌλ κΈ°λ₯μ΄ μλ€κ³ κ°μ ν΄ λ΄ μλ€. μ΄λ νΉμ λ²νΌμ λλ₯΄λ©΄ νλ μ΄μ΄κ° ννΌ λμμ νκ² λ©λλ€. λΉμ μ 4 μ’ λ₯μ μ λλ©μ΄μ μ λ§λ€μ΄μ μκ°μ μΈ νΌλλ°±μ μ£Όλ κΈ°λ₯μ μ§μν©λλ€:
"idle"
νλ μ΄μ΄ μΊλ¦ν°κ° λκΈ°νκ³ μλ λ°λ³΅ μ λλ©μ΄μ .
"dodge_idle"
A looping animation of the player character idling while being in the dodging stance. νλ μ΄μ΄ μΊλ¦ν°κ° ννΌλμμ μ§μνκ³ μλ λ°λ³΅ μ λλ©μ΄μ .
"start_dodge"
νλ μ΄μ΄ μΊλ¦ν°κ° ννΌλ₯Ό μμνλ μΌνμ±(play-once)μ κ³ΌλκΈ°(transition) μ λλ©μ΄μ .
"stop_dodge"
νλ μ΄μ΄ μΊλ¦ν°κ° ννΌλ₯Ό λλ΄λ μΌνμ±(play-once)μ κ³ΌλκΈ°(transition) μ λλ©μ΄μ .
μ΄ λ‘μ§μ μλ μ€ν¬λ¦½νΈ μ²λΌ ꡬνν μ μμ΅λλ€:
function on_input(self, action_id, action)
-- λ²νΌμ
λ ₯μ "dodge" λμμ μμν¨
if action_id == hash("dodge") then
if action.pressed then
msg.post("#sprite", "play_animation", {id = hash("start_dodge")})
-- ννΌλμ μνμΈμ§ κΈ°μ΅νκΈ°
self.dodge = true
elseif action.released then
msg.post("#sprite", "play_animation", {id = hash("stop_dodge")})
-- ννΌλμμ λλ
self.dodge = false
end
end
end
function on_message(self, message_id, message, sender)
if message_id == hash("animation_done") then
-- μ λλ©μ΄μ
μ νΈλμ§μ
μ΄ λλκ³ λ°λ³΅ μ λλ©μ΄μ
μ μμν¨
if self.dodge then
msg.post("#sprite", "play_animation", {id = hash("dodge_idle")})
else
msg.post("#sprite", "play_animation", {id = hash("idle")})
end
end
end
GUI box node example
λ Έλμ μ λλ©μ΄μ μ΄λ μ΄λ―Έμ§λ₯Ό μ ννλ μ€μλ, μ΄λ―Έμ§ μμ€(μνλΌμ€λ νμΌμμ€)μ κΈ°λ³Έ μ λλ©μ΄μ μ νλ°©μ ν λΉ ν μ μμ΅λλ€. μ΄λ―Έμ§ μμ€λ λ Έλμ μ μ μΌλ‘ μ ν λμ§λ§ νμ¬ μ λλ©μ΄μ μ νλ μ΄λ₯Ό λ°νμμμλ λ³κ²½ν μ μμ΅λλ€. μ€νΈμ»· μ΄λ―Έμ§λ€μ ν νλ μμ§λ¦¬ μ λλ©μ΄μ μ²λΌ λ€λ€μ§λ―λ‘ λ°νμμ μ΄λ―Έμ§λ₯Ό λ°κΎΌλ€λ κ²μ λ Έλμμ κ°κΈ° λ€λ₯Έ νλ¦½λΆ μ λλ©μ΄μ μ νλ μ΄ νλκ²κ³Ό μμ ν λμΌν©λλ€:
local function flipbook_done(self)
msg.post("#", "jump_completed")
end
function init(self)
local character_node = gui.get_node("character")
-- λ
Έλκ° μ΄ μμ
μ μννλ €λ©΄ μ¬μμ€μΈ μ μ λλ©μ΄μ
/μ΄λ―Έμ§μ λμΌν μνλΌμ€ λλ νμΌμμ€μ κΈ°λ³Έ μ λλ©μ΄μ
μ κ°μ§κ³ μμ΄μΌ ν©λλ€.
gui.play_flipbook(character_node, "jump_left", flipbook_done)
end
μλ£μ νΈμΆλλ μ νμ (optional) ν¨μκ° μ 곡λ μ μμ΅λλ€(μ μμ μ flipbook_done ν¨μμ²λΌ). μ΄λ ONCE__* λͺ¨λμμ μ¬μλλ μ λλ©μ΄μ μΌλ‘λΆν° νΈμΆλ©λλ€.
Animating Spine models
μ€νμΈ λͺ¨λΈμ μ λλ©μ΄μ μ μ μ©νλ €λ©΄, κ°λ¨ν spine.play_anim() ν¨μλ₯Ό νΈμΆνλ©΄ λ©λλ€:
local function anim_done(self)
-- μ λλ©μ΄μ
μ΄ μ’
λ£λκ³ , λκ° μ μ©ν μΌμ ν©λλ€...
end
function init(self)
-- "spinemodel" μ»΄ν¬λνΈμ "walk" μ λλ©μ΄μ
μ νλ μ΄νκ³ μ²« 0.1μ΄ λμ μ΄μ μ λλ©μ΄μ
κ³Ό λΈλλ©ν ν μ½λ°±μ νΈμΆν©λλ€.
local anim_props = { blend_duration = 0.1 }
spine.play_anim("#spinemodel", "walk", go.PLAYBACK_LOOP_FORWARD, anim_props, anim_done)
end

μ λλ©μ΄μ μ΄ go.PLAYBACK_ONCE_ λͺ¨λλ‘ νλ μ΄λκ³ spine.play_anim() ν¨μμ μ½λ°± ν¨μλ₯Ό λκΈ°λ©΄ μ λλ©μ΄μ μλ£μ μ΄ μ½λ°± ν¨μκ° μ€νλ©λλ€. μλμ μ½λ°±(callback) μ 보λ₯Ό μ°Έκ³ λ°λλλ€.
Cursor animation
spine.play_anim() λ₯Ό μ¬μ©ν΄μ μ€νμΈ μ λλ©μ΄μ μ μ§ννλ κ² μΈμλ, Spine Model μ»΄ν¬λνΈλ go.animate() μΌλ‘ λ€λ£° μ μλ "cursor" μμ±μ μ 곡ν©λλ€.
-- μ€νμΈ λͺ¨λΈμ μ λλ©μ΄μ
μ μ€μ νκ³ μ¬μμ μν¨
spine.play_anim("#spinemodel", "run_right", go.PLAYBACK_NONE)
-- 컀μ μμΉλ₯Ό 0μΌλ‘ μ€μ ν¨
go.set("#spinemodel", "cursor", 0)
-- 컀μλ₯Ό λλ¦¬κ² νΈμλ μν€κ³ in-out quad μ΄μ§(easing) ν¨κ³Όλ₯Ό μ£Όκ³ νν μ λλ©μ΄μ
μ²λ¦¬ν¨
go.animate("#spinemodel", "cursor", go.PLAYBACK_LOOP_PINGPONG, 1, go.EASING_INOUTQUAD, 6)
컀μκ° νΈμλ(tween)λκ±°λ μ ν λλ©΄, νμλΌμΈ μ΄λ²€νΈ(timeline events)κ° μμλλ‘ λ°μνμ§ μμ μ μμ΅λλ€.
The bone hierarchy
μ€νμΈ μ€μΌλ ν€μ κ°λ³ λΌλλ€μ κ²μ μ€λΈμ νΈμ λ΄λΆμ μΌλ‘ λνλ©λλ€. μ€νμΈ λͺ¨λΈ μ»΄ν¬λνΈμ μμλΌμΈ μ°½(Outline)μμ μ 체 κ³μΈ΅κ΅¬μ‘°κ° νμλ©λλ€. μ¬κΈ°μ μ€μΌλ ν€ κ΅¬μ‘°μ κ° λΌλμ μ΄λ¦κ³Ό μμΉλ₯Ό λ³Ό μ μμ΅λλ€.

λΌλμ μ΄λ¦μ μ¬μ©νμ¬, λ°νμμ λΌλμ μΈμ€ν΄μ€ μμ΄λλ₯Ό κ²μν μ μμ΅λλ€. spine.get_go() ν¨μλ νΉμ λΌλμ μμ΄λλ₯Ό λ°νν©λλ€. μλ₯Ό λ€μ΄, μμ§μ΄λ κ²μ μ€λΈμ νΈ μλμ λ€λ₯Έ μ€λΈμ νΈλ₯Ό μμ κ°μ²΄λ‘ λ£μ μ μμ΅λλ€:
-- heroineμ μμ κΆμ΄ μ€λΈμ νΈλ₯Ό κ°λ€ λΆμ
local hand = spine.get_go("heroine#spinemodel", "front_hand")
msg.post("pistol", "set_parent", { parent_id = hand })
Timeline events
μ€νμΈ μ λλ©μ΄μ μ μ νν μκ°μ λ©μΈμ§λ₯Ό 보λ΄μ μ΄λ²€νΈλ₯Ό νΈλ¦¬κ±° ν μ μμ΅λλ€. μ΄λ λ°μκ΅ μ리λ₯Ό μ¬μνκ±°λ, νν°ν΄ ν¨κ³Όλ₯Ό μ€ν°νκ±°λ, λΌλ κ³μΈ΅κ΅¬μ‘°μ μ€λΈμ νΈλ₯Ό λΆμ΄κ³ λΌκ±°λ νλ λ±λ±μ μ΄λ²€νΈλ₯Ό μ λλ©μ΄μ κ³Ό λκΈ°ν λμ΄ λ°°μΉ ν΄μΌλ§ νλ κ²½μ°μ λ§€μ° μ μ©ν©λλ€.
μ΄λ²€νΈλ€μ μ€νμΈ μννΈμ¨μ΄μμ μΆκ°ν μ μμΌλ©° νλ μ΄λ°± νμλΌμΈ(playback timeline)μμ μκ°ν λ©λλ€:

κ° μ΄λ²€νΈλ μ΄λ¦ μλ³μ(name identifier: μ μμ μμ "bump")λ‘ μ°Έμ‘°λλ©° νμλΌμΈμ κ° μ΄λ²€νΈ μΈμ€ν΄μ€λ μΆκ° μ 보λ₯Ό ν¬ν¨ν μ μμ΅λλ€:
Integer
μ μν μ«μκ°
Float
λΆλμμμ μ«μκ°
String
λ¬Έμμ΄ κ°
μ λλ©μ΄μ μ΄ νλ μ΄λκ³ νμλΌμΈ μ΄λ²€νΈκ° λ°μνλ©΄, spine_event λ©μΈμ§κ° spine.play()λ₯Ό νΈμΆνλ μ€ν¬λ¦½νΈ μ»΄ν¬λνΈλ‘ μ μ‘λ©λλ€. μ΄ λ©μΈμ§ λ°μ΄ν°μλ μ΄λ²€νΈμ λ΄μ₯λ 컀μ€ν μ«μλ λ¬Έμμ΄ λΏλ§ μλλΌ λλ‘λ μ μ©ν μΆκ°μ μΈ νλλ ν¬ν¨νκ³ μμ΅λλ€:
t
μ λλ©μ΄μ μ 첫 λ²μ§Έ νλ μ μ΄ν κ²½κ³Όλ μκ°(μ΄)
animation_id
μ λλ©μ΄μ μ΄λ¦, ν΄μ¬(hash)λ¨
string
μ 곡λ λ¬Έμμ΄ κ°, ν΄μ¬(hash)λ¨
float
μ 곡λ λΆλ μμμ μ«μκ°
integer
μ 곡λ μ μν μ«μκ°
event_id
μ΄λ²€νΈ μλ³μ, ν΄μ¬(hash)λ¨
blend_weight
μ λλ©μ΄μ μ΄ μΌλ§λ λΈλ λ(blend) λμλμ§μ λν κ°. 0μ νμ¬ μ λλ©μ΄μ μ΄ μμ§ λΈλ λμ μΌλΆλΆμ΄ μλμ μλ―Ένλ©°, 1μ νμ¬ μ λλ©μ΄μ μ΄ 100%λ‘ κ΅¬μ±λ λΈλ λ λΌλκ²μ μλ―Έν¨.
-- μ€νμΈ μ λλ©μ΄μ
μ΄ μ λλ©μ΄μ
κ³Ό λκΈ°νλ μ¬μ΄λλ₯Ό νλ μ΄νκΈ° μν΄ μ΄λ²€νΈλ₯Ό ν¬ν¨νκ³ μμ.
-- μ¬κΈ°λ‘ λ©μΈμ§κ° λμ°©ν¨.
function on_message(self, message_id, message, sender)
if message_id == hash("spine_event") and message.event_id == hash("play_sound") then
-- μ λλ©μ΄μ
μ¬μ΄λ νλ μ΄νκΈ°. 컀μ€ν
μ΄λ²€νΈ λ°μ΄ν°μ μ¬μ΄λ μ»΄ν¬λνΈ μ΄λ¦κ³Ό μΆλ ₯κ°(gain)μ΄ λ€μ΄ μμ
local url = msg.url("sounds")
url.fragment = message.string
msg.post(url, "play_sound", { gain = message.float })
end
end
3D Model animation
λͺ¨λΈμ model.play_anim() ν¨μλ₯Ό μ¬μ©ν΄μ μ λλ©μ΄μ λ©λλ€:
function init(self)
-- #modelμμ μλ€λ‘ μμ§μ΄λ "wiggle" μ λλ©μ΄μ
μμ
model.play_anim("#model", "wiggle", go.PLAYBACK_LOOP_PINGPONG)
end
Defoldλ νμ¬ νμ¬ λ² μ΄ν¬ μ λλ©μ΄μ (baked animations)λ§ μ§μν©λλ€. μ λλ©μ΄μ μ ν€νλ μλ§λ€ κ°κ°μ μ λλ©μ΄μ λ³Έ(animated bone)μ μν λ©νΈλ¦μ€λ₯Ό κ°μ ΈμΌ νλ©° μμΉ, νμ , μ€μΌμΌμ λ³λμ ν€λ‘ κ°μ§μ§ λ§μμΌ ν©λλ€.
λν μ λλ©μ΄μ μ μ νμ μΌλ‘ 보κ°(linearly interpolated)λ©λλ€. κ³ κΈ κ³‘μ 보κ°(curve interpolation)μ νλ €λ©΄ μ λλ©μ΄μ μ μ΅μ€ν¬ν°(exporter)μμ 미리 ꡬμ(prebake)μΌ ν©λλ€.
Colladaμ μ λλ©μ΄μ ν΄λ¦½(Animation clip)μ μ§μνμ§ μμ΅λλ€. λͺ¨λΈλ³λ‘ λ€μμ μ λλ©μ΄μ μ μ¬μ©νκΈ° μν΄μλ κ°κ° λ³λμ .dae νμΌλ‘ μ΅μ€ν¬νΈ νκ³ Defoldμ .animationset νμΌλ‘ ν©μ³μΌ ν©λλ€.
The bone hierarchy
λͺ¨λΈ μ€μΌλ ν€μ λΌλλ€μ κ²μ μ€λΈμ νΈμ λ΄λΆμ μΌλ‘ λνλ©λλ€. λͺ¨λΈ μ»΄ν¬λνΈμ μμλΌμΈ μ°½(Outline)μμ λΌλμ κ³μΈ΅κ΅¬μ‘°μ κ° λΌλμ μ΄λ¦μ λ³Ό μ μμ΅λλ€.

λ°νμμ λΌλ κ²μμ€λΈμ νΈμ μΈμ€ν΄μ€ μμ΄λλ₯Ό νμν μ μμ΅λλ€. model.get_go() ν¨μλ νΉμ λΌλμ μμ΄λλ₯Ό λ°νν©λλ€.
-- wiggler λͺ¨λΈμ μ€κ° λΌλ₯Ό κ°μ Έμ΄
local bone_go = model.get_go("#wiggler", "Bone_002")
-- μ΄μ κ²μ μ€λΈμ νΈλ‘ λκ° μ μ©ν μμ
μ ν΄λ³ΌκΉλ...
Cursor animation
μ€νμΈ λͺ¨λΈκ³Ό λ§μ°¬κ°μ§λ‘, 3D λͺ¨λΈμ "cursor" μμ±μ μ‘°μν΄μ μ λλ©μ΄μ μ μ²λ¦¬ν μ μμ΅λλ€:
-- #modelμ μ λλ©μ΄μ
μ μ€μ νκ³ μ¬μμ μμ§ μν¨
model.play_anim("#model", "wiggle", go.PLAYBACK_NONE)
-- μ λλ©μ΄μ
μ μμμ μΌλ‘ 컀μλ₯Ό μ
ν
ν¨
go.set("#model", "cursor", 0)
-- 0κ³Ό 1 μ¬μ΄λ‘ 컀μλ₯Ό νΈμλ(Tween)ν¨
go.animate("#model", "cursor", go.PLAYBACK_LOOP_PINGPONG, 1, go.EASING_INOUTQUAD, 3)
Property animation
κ²μ μ€λΈμ νΈλ μ»΄ν¬λνΈμ μμ±κ°μ μ λλ©μ΄μ μ²λ¦¬νκΈ° μν΄μλ go.animate() ν¨μλ₯Ό μ¬μ©ν΄μΌ ν©λλ€. GUI λ Έλ μμ±μ μν΄μλ gui.animate() λ₯Ό μ¬μ©νλ©΄ λ©λλ€.
-- μ»΄ν¬λνΈμ positionμ y μμ±κ°μ 200μΌλ‘ μ€μ
go.set(".", "position.y", 200)
-- κ·Έλ¦¬κ³ μ λλ©μ΄μ
μν΄
go.animate(".", "position.y", go.PLAYBACK_LOOP_PINGPONG, 100, go.EASING_OUTBOUNCE, 2)
μ£Όμ΄μ§ μμ±μ λͺ¨λ μ λλ©μ΄μ μ μ€μ§νλ €λ©΄, go.cancel_animations() λ₯Ό νΈμΆνκ±°λ GUI λ Έλμμλ gui.cancel_animation()λ₯Ό νΈμΆνλ©΄ λ©λλ€:
-- νμ¬ κ²μμ€λΈμ νΈμμ μ€μΌλ¬(euler) zμΆμ νμ μ λλ©μ΄μ
μ μ€μ§ν¨
go.cancel_animation(".", "euler.z")
λ§μ½ "position"κ³Ό κ°μ΄ 볡ν©μ μΈ(composite) μμ±μ μ λλ©μ΄μ μ μ·¨μνλ©΄, νμ μμλ€("position.x", "position.y", "position.z")μ μ λλ©μ΄μ λ ν¨κ» μ·¨μλ©λλ€.
Properties λ§€λ΄μΌμ κ²μ μ€λΈμ νΈ, μ»΄ν¬λνΈ, GUIλ Έλμ λͺ¨λ μμ±λ€μ λν μ€λͺ μ΄ μμ΅λλ€.
GUI node property animation
λλΆλΆμ λͺ¨λ GUI λ Έλ μμ±λ€μ μ λλ©μ΄μ κ°λ₯ν©λλ€. μλ₯Ό λ€μ΄, "color" μμ±μ μ€μ ν΄μ ν¬λͺ κ°μ μ‘°μ νμ¬ λ Έλλ₯Ό 보μ΄μ§ μκ² λ§λ νμ, μμμ νμκ²(tint 컬λ¬κ° μλ) μ λλ©μ΄μ μ²λ¦¬ν΄μ νμ΄λμΈ ν¨κ³Όλ₯Ό μ€ μ μμ΅λλ€.
local node = gui.get_node("button")
local color = gui.get_color(node)
-- μμμ νμκ² μ λλ©μ΄μ
μ²λ¦¬νκΈ°
gui.animate(node, gui.PROP_COLOR, vmath.vector4(1, 1, 1, 1), gui.EASING_INOUTQUAD, 0.5)
-- μΈκ³½μ λΆμμμΌλ‘ μ λλ©μ΄μ
μ²λ¦¬νκΈ°
gui.animate(node, "outline.x", 1, gui.EASING_INOUTQUAD, 0.5)
-- κ·Έλ¦¬κ³ xμ’νλ₯Ό 100μΌλ‘ μ΄λμν€κΈ°
gui.animate(node, hash("position.x"), 100, gui.EASING_INOUTQUAD, 0.5)
Playback Modes
μ λλ©μ΄μ μ ν λ² λλ λ°λ³΅μ μΌλ‘ μ¬μλ μ μμ΅λλ€. μ λλ©μ΄μ μ¬μ λ°©λ²μ νλ μ΄λ°± λͺ¨λ(playback mode)μ μν΄ κ²°μ λ©λλ€:
- go.PLAYBACK_NONE
- go.PLAYBACK_ONCE_FORWARD
- go.PLAYBACK_ONCE_BACKWARD
- go.PLAYBACK_ONCE_PINGPONG
- go.PLAYBACK_LOOP_FORWARD
- go.PLAYBACK_LOOP_BACKWARD
- go.PLAYBACK_LOOP_PINGPONG
νν(pingpong) λͺ¨λλ μ λλ©μ΄μ μ μ²μμ μ λ°©ν₯μΌλ‘ μ¬μνκ³ , λ€μμ μλ°©ν₯μΌλ‘ μ¬μν©λλ€. GUI μμ±μ μ λλ©μ΄μ νκΈ° μν λͺ¨λλ μλμ κ°μ΅λλ€:
- gui.PLAYBACK_NONE
- gui.PLAYBACK_ONCE_FORWARD
- gui.PLAYBACK_ONCE_BACKWARD
- gui.PLAYBACK_ONCE_PINGPONG
- gui.PLAYBACK_LOOP_FORWARD
- gui.PLAYBACK_LOOP_BACKWARD
- gui.PLAYBACK_LOOP_PINGPONG
Easing
μ΄μ§(easing)μ μ λλ©μ΄μ κ°μ΄ μκ°μ λ°λΌ μ΄λ»κ² λ³ννλμ§λ₯Ό μ μν©λλ€. μλ μ΄λ―Έμ§λ€μ μ΄μ§μ μ’ λ₯λ³λ‘ μκ°μ λ°λ₯Έ λ³νλ₯Ό κ·Έλνλ‘ μ€λͺ νκ³ μμ΅λλ€.
go.animate() λ₯Ό νΈμΆν λ μ¬μ©νλ μ λΉν κ°μ go.EASING_LINEAR, go.EASING_INBACK, go.EASING_OUTBACK λ±μ΄ μμ΅λλ€.
gui.animate() λ₯Ό νΈμΆν λ μ¬μ©νλ κ°μ gui.EASING_LINEAR, gui.EASING_INBACK, gui.EASING_OUTBACK λ±μ λλ€.

Custom easing
κ°μ λͺ¨μ(set of values)μΌλ‘ 벑ν°(vector)λ₯Ό μ μν΄μ μμμ 미리 μ μλ μ΄μ§ μμ(easing constants) λμ μ μ΄μ§ 컀λΈ(easing curve)λ₯Ό 컀μ€ν νκ² λ§λ€ μ μμ΅λλ€:
local values = { 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1 }
local square_easing = vmath.vector(values)
go.animate("go", "position.y", go.PLAYBACK_LOOP_PINGPONG, 100, square_easing, 2.0)
Completion callbacks
λͺ¨λ μ λλ©μ΄μ ν¨μ(go.animate(), gui.animate(), gui.play_flipbook(), gui.play_spine_anim(), spine.play_anim(), model.play_anim())λ λ§μ§λ§ μΈμκ°μΌλ‘ μ νμ μΈ Lua μ½λ°± ν¨μ(optional Lua callback function)λ₯Ό μ§μν©λλ€. μ΄ ν¨μλ μ λλ©μ΄μ μ μ¬μμ΄ μ’ λ£λλ©΄ νΈμΆλ©λλ€. μ΄ ν¨μλ 루ν μ λλ©μ΄μ μΌ κ²½μ°μ΄κ±°λ μ λλ©μ΄μ μ΄ go.cancel_animations()λ‘ μλμ μΌλ‘ μ·¨μ λμμ κ²½μ°μ νΈμΆλμ§ μμ΅λλ€. μ½λ°±μ μ λλ©μ΄μ μλ£μ μ΄λ²€νΈλ₯Ό νΈλ¦¬κ±°νκ±°λ μ¬λ¬ μ λλ©μ΄μ μ ν¨κ» μ°κ²°νλλ° μ¬μ©λ©λλ€.
μ½λ°±μ μ νν ν¨μ νν(signature)λ μ λλ©μ΄μ ν¨μλ§λ€ μ‘°κΈμ© λ€λ¦ λλ€. μμΈν κ²μ API λ¬Έμλ₯Ό μ°Έκ³ λ°λλλ€.
local function done_bouncing(self, url, property)
-- μ λλ©μ΄μ
μ λλλ€.. μ΄μ λκ° ν΄λ³΄μ...
end
function init(self)
go.animate(".", "position.y", go.PLAYBACK_ONCE_FORWARD, 100, go.EASING_OUTBOUNCE, 2, 0, done_bouncing)
end