AnimationTree Durum Makineleri
Godot 4'te

Durum makineleri, geçişler, blend tree'ler, OneShot, travel() ve koşullara dair eksiksiz rehber — gerçek GDScript kod örnekleriyle.

1. Giriş

AnimationTree, Godot 4'ün karmaşık animasyon blend'i ve durum geçişleri için sunduğu sistemdir. Kodunuzun her yerine dağılmış AnimationPlayer.play() çağrılarıyla birden fazla animasyonu yönetmeye çalıştıysanız, bunun ne kadar çabuk kontrolden çıktığını bilirsiniz. AnimationTree, bunu görsel bir durum ve geçiş grafiğiyle çözer.

Son derece güçlü olmasına rağmen AnimationTree'nin resmi dokümantasyonu yetersizdir ve geliştiricileri sıklıkla tahmin yürütmek zorunda bırakır. Bu rehber, temel kurulumdan ileri düzey blend tree'lere kadar her şeyi, projenize doğrudan kopyalayabileceğiniz gerçek GDScript koduyla adım adım anlatır.

Neler öğreneceksiniz

Durum makineleri, geçişler, blend space'ler (1D & 2D), saldırılar için OneShot, travel() ve koşullar ve eksiksiz bir karakter kontrolcüsü deseni.

2. Ön Koşullar

AnimationTree'nizi kurmadan önce şunlara ihtiyacınız var:

  • En azından Idle, Walk, Run ve Jump animasyonları önceden oluşturulmuş bir AnimationPlayer node'u
  • AnimationPlayer, AnimationTree'yi eklediğiniz node'un kardeşi veya alt öğesi olmalıdır (genellikle her ikisi de karakter kök node'unuzun alt öğeleridir)
  • Godot 4.x (bu rehber Godot 4 API'sini kullanır — AnimationTree API'si Godot 3'e kıyasla önemli ölçüde değişti)
Godot 3 ve Godot 4

Godot 4'te AnimationTree.animation_player yerini AnimationTree.anim_player'a bıraktı. Oynatma için parametre yolu da değişti. Godot 3'ten geçiş yapıyorsanız resmi geçiş rehberine göz atın.

3. Temel Kurulum

Bir AnimationTree'nin kurulumu dört adımda gerçekleşir:

  1. Bir AnimationTree node'u ekleyin — Onu, AnimationPlayer'ınızın yanında karakterinizin (ör. CharacterBody2D veya CharacterBody3D) alt öğesi olarak ekleyin.
  2. anim_player ayarlayın — Inspector'da "Anim Player" özelliğini AnimationPlayer node'unuza yönlendirin.
  3. tree_root ayarlayın — Inspector'da "Tree Root" özelliğine tıklayın ve yeni bir AnimationNodeStateMachine oluşturun.
  4. active = true yapın — Inspector'da "Active" onay kutusunu işaretleyin veya koddan ayarlayın.

Sahne ağacınız şöyle görünmelidir:

CharacterBody2D (or CharacterBody3D)
  +-- Sprite2D (or Sprite3D)
  +-- CollisionShape2D
  +-- AnimationPlayer      <-- has Idle, Walk, Run, Jump animations
  +-- AnimationTree         <-- points to AnimationPlayer above
GDScript
# Minimal code setup (usually done via the editor instead):
@onready var anim_tree: AnimationTree = $AnimationTree

func _ready() -> void:
    # If you set these in the Inspector, you don't need this code
    anim_tree.anim_player = ^"../AnimationPlayer"
    anim_tree.tree_root = AnimationNodeStateMachine.new()
    anim_tree.active = true
Editör mü, kod mu?

Pratikte AnimationTree'yi neredeyse her zaman editörde yapılandırırsınız. Yukarıdaki kod bütünlük için verilmiştir, ancak genellikle betiğinizde yalnızca anim_tree.active = true'ya ihtiyacınız olur (ve bunu bile editörde ayarlayabilirsiniz).

4. Durum Makinesi Temelleri

AnimationTree'deki bir durum makinesi basit bir kavrama dayanır: durumlar animasyonları temsil eder ve geçişler bunlar arasında geçiş yapma koşullarını tanımlar.

Durum Ekleme

AnimationTree'nizin tree_root'u bir AnimationNodeStateMachine olduğunda, durum makinesi editörünü açmak için Inspector'da üzerine çift tıklayın:

  1. Grafik alanına sağ tıklayın ve Add Animation seçeneğini seçin
  2. AnimationPlayer'ınızdan bir animasyon seçin (Idle, Walk, Run, Jump vb.)
  3. İhtiyacınız olan her animasyon durumu için tekrarlayın
Özel Durumlar

Start giriş noktasıdır — ilk geçiş her zaman burada başlar. End isteğe bağlıdır ve durum makinesinin tamamlandığını belirtir (iç içe durum makineleri için kullanışlıdır).

Geçiş Ekleme

İki durum arasında bir geçiş oluşturmak için:

  1. Kaynak durum node'una tıklayın
  2. Bir geçiş oku oluşturmak için hedef duruma sürükleyin
  3. Inspector'da yapılandırmak için geçiş okuna tıklayın

Geçiş Özellikleri

Özellik Açıklama
advance_mode Auto — koşulu doğru olduğunda tetiklenir. Enabled — travel() için her zaman kullanılabilir. Disabled — engellenir.
advance_condition Bir boolean parametresinin adı (ör. is_moving). Doğru olduğunda geçiş otomatik tetiklenir.
xfade_time Saniye cinsinden crossfade süresi. Animasyonlar arasında yumuşak blend. Tipik: 0,1 – 0,3 sn.
switch_mode Immediate — hemen geç. Sync — oynatma konumunu eşle. AtEnd — mevcut animasyonun bitmesini bekle.

Bir platform oyunu karakteri için tipik bir kurulum:

Start --> Idle
Idle  --> Walk   (condition: is_moving)
Walk  --> Idle   (condition: is_idle)
Idle  --> Jump   (condition: is_jumping)
Walk  --> Jump   (condition: is_jumping)
Jump  --> Fall   (condition: is_falling)
Fall  --> Idle   (condition: is_on_floor, switch_mode: Immediate)

5. Durum Makinesini Koddan Kontrol Etme

Durum makinesini yönlendirmenin iki temel yolu vardır: koşul parametreleri ayarlamak (otomatik geçişler) ve travel() çağırmak (manuel geçişler). Her iki yaklaşımı birleştirebilirsiniz.

GDScript
extends CharacterBody2D

@onready var anim_tree: AnimationTree = $AnimationTree
@onready var state_machine: AnimationNodeStateMachinePlayback = anim_tree.get("parameters/playback")

func _physics_process(delta: float) -> void:
    # ... movement logic here ...
    move_and_slide()
    _update_animation_parameters()

func _update_animation_parameters() -> void:
    # Approach 1: Set condition parameters — transitions fire automatically
    anim_tree.set("parameters/conditions/is_moving", velocity.length() > 10.0)
    anim_tree.set("parameters/conditions/is_idle", velocity.length() <= 10.0)
    anim_tree.set("parameters/conditions/is_on_floor", is_on_floor())
    anim_tree.set("parameters/conditions/is_jumping", velocity.y < 0 and not is_on_floor())
    anim_tree.set("parameters/conditions/is_falling", velocity.y > 0 and not is_on_floor())

    # Approach 2: Use travel() for direct control
    # if velocity.length() > 10.0:
    #     state_machine.travel("Walk")
    # else:
    #     state_machine.travel("Idle")
Parametre Yolları

Parametreler, geçişlerde ayarlanan koşullar için parameters/conditions/<condition_name> desenini izler. Koşul adı, editörde geçişte ayarladığınız advance_condition ile eşleşmelidir.

6. travel() ve Koşullar

Koşul Tabanlı (Hareket için Önerilir)

Her karede boolean parametreleri ayarlayın ve geçişlerin otomatik tetiklenmesine izin verin. Bu daha bildirimseldir ve kodunuzu temiz tutar. Durum makinesi, geçiş mantığını, crossfade'leri ve uç durumları sizin yerinize halleder.

# Declarative: just describe the current state of the world
anim_tree.set("parameters/conditions/is_moving", velocity.length() > 10.0)
anim_tree.set("parameters/conditions/is_on_floor", is_on_floor())

travel() (Tek Seferlik Aksiyonlar için Önerilir)

travel() bir durum geçişi talep eder. Geçiş kurallarına uyar — mevcut durumdan hedefe geçerli bir yol yoksa çağrı yok sayılır. Bu, onu tekrar tekrar çağırmayı güvenli kılar. Saldırılar, emote'lar veya ara sahne animasyonları gibi tek seferlik tetikleyiciler için kullanın.

# travel() — requests a transition (respects transition rules)
state_machine.travel("Jump")

# Get current state name
var current: StringName = state_machine.get_current_node()
print(current)  # "Idle", "Walk", etc.

# Check if travel is possible
var is_playing: bool = state_machine.is_playing()
print(is_playing)
Hangisini ne zaman kullanmalı?

Koşullar, sürekli durumlar (idle, walk, run, fall) için. travel(), olay tetiklemeli durumlar (saldırı, kaçınma, etkileşim) için. Birçok proje her ikisini de kullanır: hareket için koşullar, savaş aksiyonları için travel().

7. Blend Tree'ler

Blend tree'ler, ayrık durumlar arasında sert geçiş yapmak yerine sürekli bir değere göre birden fazla animasyon arasında yumuşakça enterpolasyon yapmanızı sağlar. Yürüme/koşma hızı blend'i ve yönlü hareket için mükemmeldir.

BlendSpace1D

Tek bir eksen boyunca iki veya daha fazla animasyon arasında bir 1D blend. Yaygın kullanım: hareket hızına göre Walk ile Run'ın blend'lenmesi.

Editörde, durum makinenizin içinde (veya bağımsız bir tree root olarak) bir BlendSpace1D node'u oluşturun. Animasyon noktaları ekleyin:

# BlendSpace1D setup (in editor):
# Point 0.0 = Walk animation
# Point 1.0 = Run animation

# Control from code:
var speed_factor: float = clamp(velocity.length() / max_speed, 0.0, 1.0)
anim_tree.set("parameters/WalkRun/blend_position", speed_factor)

BlendSpace2D

İki eksen kullanan bir 2D blend. 8 yönlü hareket veya karakterin herhangi bir yöne hareket edebildiği yukarıdan bakışlı oyunlar için mükemmeldir.

# BlendSpace2D setup (in editor):
# Place animations at positions:
#   Idle at (0, 0)
#   WalkRight at (1, 0), WalkLeft at (-1, 0)
#   WalkUp at (0, -1), WalkDown at (0, 1)
#   Diagonals at corners

# Control from code:
var input_dir := Input.get_vector("move_left", "move_right", "move_up", "move_down")
anim_tree.set("parameters/Movement/blend_position", input_dir)
Blend Modları

BlendSpace2D birden fazla blend modunu destekler: varsayılan üçgenleme çoğu durumda iyi çalışır. Enterpolasyon olmadan piksel-art tarzı animasyon isterseniz ayrık modu (en yakın noktaya sıçrar) da seçebilirsiniz.

8. Yaygın Node Tipleri

AnimationTree, karmaşık animasyon davranışları oluşturmak için birleştirilebilen çeşitli node tiplerini destekler:

Node Tipi Kullanım Alanı
AnimationNodeStateMachine Geçişli durum makinesi. En yaygın kök node. Durumlar animasyonlar veya iç içe durum makineleri olabilir.
AnimationNodeBlendSpace1D Tek eksen boyunca 1D blend. Yürüme/koşma hızı, nişan açısı vb.
AnimationNodeBlendSpace2D İki eksen kullanan 2D blend. Yönlü hareket, yan yürüme (strafe) blend'i.
AnimationNodeBlendTree Blend işlemlerinden oluşan bir grafik. Birden fazla blend node'unu özel mantıkla birleştirir.
AnimationNodeAdd2 Toplamsal blend. Bir animasyonu diğerinin üzerine katmanlar (ör. yürümenin üzerine nişan ofseti).
AnimationNodeTimeScale Hız kontrolü. Bir animasyonu çalışma zamanında daha hızlı veya daha yavaş oynatır.
AnimationNodeOneShot Tek seferlik animasyon katmanı. Saldırılar, emote'lar, isabet tepkileri için mükemmel.
AnimationNodeTransition Crossfade'lerle birden fazla giriş arasında geçiş yapar. Daha basit kurulumlar için durum makinelerine alternatif.

9. OneShot Deseni (Saldırılar, Emote'lar)

OneShot node'u AnimationTree'deki en kullanışlı desenlerden biridir. Temel animasyonunuzun üzerinde tek seferlik bir animasyon oynatır (yürürken bir saldırı savurmasını oynatmak gibi) ve ardından otomatik olarak temel animasyona döner.

BlendTree İçinde Kurulum

OneShot kullanmak için AnimationTree kökünüzün (veya içindeki bir durumun) bir BlendTree olması gerekir:

# BlendTree graph setup:
#
#   [StateMachine] ---> [OneShot "AttackOneShot"] ---> [Output]
#   (base locomotion)      ^
#                          |
#                   [Animation "Attack"]
#                   (shot input)
#
# The StateMachine provides the base (idle/walk/run).
# The Attack animation is connected to the OneShot's "shot" input.

Koddan Tetikleme

GDScript
extends CharacterBody2D

@onready var anim_tree: AnimationTree = $AnimationTree

func _input(event: InputEvent) -> void:
    if event.is_action_pressed("attack"):
        _play_attack()

func _play_attack() -> void:
    # Fire the one-shot animation
    anim_tree.set(
        "parameters/AttackOneShot/request",
        AnimationNodeOneShot.ONE_SHOT_REQUEST_FIRE
    )

func _process(delta: float) -> void:
    # Check if the one-shot is currently active
    var is_attacking: bool = anim_tree.get("parameters/AttackOneShot/active")
    if is_attacking:
        # Optionally disable movement during attack
        pass

OneShot İstek Sabitleri

Sabit Etki
ONE_SHOT_REQUEST_FIRE OneShot animasyonunu oynatmaya başlar
ONE_SHOT_REQUEST_ABORT OneShot'ı iptal eder ve hemen temele döner
ONE_SHOT_REQUEST_FADE_OUT OneShot'ı kaybolarak söndürür (fadeout_time özelliğini kullanır)
Birden Fazla Saldırı

Kombo sistemleri için, ardışık olarak birden fazla OneShot node'u kullanın veya OneShot'ın "shot" girişinde Attack1 → Attack2 → Attack3 durumlarına sahip iç içe bir durum makinesi kullanın.

10. Pratik Örnek: Eksiksiz Karakter Kontrolcüsü

İşte durum makinesi hareketini bir OneShot saldırısıyla birleştiren eksiksiz bir 2D platform oyunu karakter betiği. Bu, kendi projenize uyarlayabileceğiniz üretime hazır bir desendir.

GDScript — player.gd
extends CharacterBody2D

const SPEED := 200.0
const JUMP_VELOCITY := -350.0
const SPRINT_MULTIPLIER := 1.6

@onready var anim_tree: AnimationTree = $AnimationTree
@onready var playback: AnimationNodeStateMachinePlayback = anim_tree.get("parameters/playback")
@onready var sprite: Sprite2D = $Sprite2D

var gravity: float = ProjectSettings.get_setting("physics/2d/default_gravity")

func _ready() -> void:
    anim_tree.active = true

func _physics_process(delta: float) -> void:
    _apply_gravity(delta)
    _handle_jump()
    _handle_movement()
    move_and_slide()
    _update_animation()

func _apply_gravity(delta: float) -> void:
    if not is_on_floor():
        velocity.y += gravity * delta

func _handle_jump() -> void:
    if Input.is_action_just_pressed("jump") and is_on_floor():
        velocity.y = JUMP_VELOCITY

func _handle_movement() -> void:
    var direction := Input.get_axis("move_left", "move_right")
    var is_sprinting := Input.is_action_pressed("sprint")
    var current_speed := SPEED * (SPRINT_MULTIPLIER if is_sprinting else 1.0)

    if direction != 0.0:
        velocity.x = direction * current_speed
        sprite.flip_h = direction < 0.0
    else:
        velocity.x = move_toward(velocity.x, 0.0, SPEED)

func _update_animation() -> void:
    # Skip animation updates during attack
    var is_attacking: bool = anim_tree.get("parameters/AttackOneShot/active")
    if is_attacking:
        return

    if not is_on_floor():
        if velocity.y < 0:
            playback.travel("Jump")
        else:
            playback.travel("Fall")
    elif abs(velocity.x) > 10.0:
        if Input.is_action_pressed("sprint"):
            playback.travel("Run")
        else:
            playback.travel("Walk")
    else:
        playback.travel("Idle")

func _input(event: InputEvent) -> void:
    if event.is_action_pressed("attack") and is_on_floor():
        anim_tree.set(
            "parameters/AttackOneShot/request",
            AnimationNodeOneShot.ONE_SHOT_REQUEST_FIRE
        )
Bu Örnek için AnimationTree Yapısı

Kök = BlendTree. İçinde: bir StateMachine node'u (Idle/Walk/Run/Jump/Fall durumlarıyla) bir OneShot node'una ("AttackOneShot") bağlı, o da Output'a bağlı. Saldırı animasyonu OneShot'ın "shot" girişine bağlıdır.

11. Sorun Giderme

"Animasyon oynatılmıyor"

AnimationTree üzerinde active = true olduğunu ve anim_player özelliğinin geçerli bir AnimationPlayer'a işaret ettiğini kontrol edin. Ayrıca AnimationPlayer'ın referans verdiğiniz adlara sahip animasyonları gerçekten içerdiğini doğrulayın.

"travel() hiçbir şey yapmıyor"

Mevcut durum ile hedef durum arasında geçerli bir geçiş yolu bulunduğundan emin olun. travel(), bir yol yoksa sessizce başarısız olur. Aslında hangi durumda olduğunuzu hata ayıklamak için state_machine.get_current_node() kullanın.

"Blend çalışmıyor"

blend_position değerinizin blend space noktalarınızın aralığına düştüğünü kontrol edin. Noktalarınız 0.0 ve 1.0'daysa, 5.0 değeri beklendiği gibi çalışmaz. clamp() kullanın.

"Warning: AnimationTree is not active"

active = true'yu editörde (Inspector onay kutusu) veya _ready() fonksiyonunuzda ayarlayın. AnimationTree etkinleştirilene kadar hiçbir şey yapmaz.

"Koşul tabanlı geçiş tetiklenmiyor"

Şunları dikkatlice kontrol edin: (1) geçişin advance_mode değerinin Auto olarak ayarlandığını, (2) advance_condition adının kodda ayarladığınızla tam olarak eşleştiğini (büyük/küçük harfe duyarlı), ve (3) parametreyi _physics_process() içinde her karede ayarladığınızı.

"Animasyon oynuyor ama karakter hareket etmiyor"

AnimationTree yalnızca animasyon oynatmayı yönetir. Hareket mantığı (velocity, move_and_slide()) bundan ayrıdır ve betiğinizin _physics_process() fonksiyonunda uygulanmalıdır.

AnimationTree'nizi Yapay Zekânın Kurmasını İster misiniz?

Godot MCP Pro durum makineleri oluşturabilir, durumlar ve geçişler ekleyebilir, blend tree'leri yapılandırabilir ve parametreler ayarlayabilir — hepsi tek bir prompt'tan. Yapay zeka asistanınıza istediğiniz animasyon davranışını söyleyin, o da tüm AnimationTree'yi sizin için kursun.

  • create_animation_tree
  • add_state_machine_state
  • add_state_machine_transition
  • set_blend_tree_node
  • set_tree_parameter
  • get_animation_tree_structure
Godot MCP Pro'yu Edinin — $15