Dizine dön

Merdiven — Yöntem Brifingi

Traversal R-009 Çizen: Alparslan Tamam

Dikey hareket katmanının ilk parçası: merdiven geçişini üç bağımsız katmana (poz sürekliliği, uzaysal hizalama, zamansal hizalama) ayırır; motorun değiştirilemez gerçeklerini (Walking/Falling'de Z root motion yok sayılır, Root Motion Mode'un Game Thread bedeli) ve adım adım merdiven prosedürünü verir. Hem mekanizmayı anlatır hem uygulama prosedürünü içerir; her teknik iddia adı konmuş bir kaynağa bağlıdır.

Dikey hareket araştırmasının ilk uygulama parçası. Mekanizma ile prosedür bir arada, çünkü ayrıldıklarında ikisi de bozuluyor: prosedürsüz anlatım uygulanamıyor, anlatımsız prosedür denetlenemiyor.

Mekanizma dersi — üç ayrı katman

Geçiş hissi tek bir şey değil, üç bağımsız katmanın toplamı. Bunları karıştırmak en yaygın hata: yanlış katmanı ayarlayıp sorunun geçmemesine şaşırmak.

Katman Ne yapar Eksikse ne hissedilir
Poz sürekliliği İki animasyon arasındaki ani poz/hız farkını söndürür “Snap” — karakter zıplayarak yeni poza geçer
Uzaysal hizalama Animasyonun kat ettiği yolu dünyadaki hedefe oturtur “Işınlanma / boşluğa tutunma” — el basamağa değmez, gövde kenara denk gelmez
Zamansal hizalama Animasyonun zamanını mesafeyle sürer “Ayak kayması / yüzme” — ayaklar zeminde kayar

Üçü de eksikse mekanik çalışır ama geçiş hissi boş kalır.

Poz sürekliliği — Inertialization

Klasik geçiş iki animasyonu aynı anda değerlendirip aralarında cross-fade yapar. David Bollo’nun (The Coalition, Gears of War 4) tezi şu: asıl maliyet blend değil, iki animasyonu birden evaluate etmek (Bollo, GDC 2018).

Inertialization’ın fikri tersine çeviriyor: kaynağı anında kes, hedefe geç, ortaya çıkan süreksizliği bir post-process olarak söndür. Yani blend artık iki animasyon arasında değil, tek animasyonun üstünde bir düzeltme katmanı.

Kritik ayrıntı — Bollo’nun slaytları fikri kademeli kuruyor: yalnızca poz farkını söndürmek yetmiyor, çünkü poz sürekli olsa da hız süreksiz kalıyor ve gözle “duraklama” olarak görülüyor. Doğru çözüm kaynağın hızını da hatırlayıp başlangıç hızını eşleştirmek.

Pratik anlamı: blend süresini uzatarak snap’i çözmeye çalışmak yanlış koldur. Snap poz hızının süreksizliğinden gelir; çözüm inertialization düğümünü doğru yere koymaktır, süreyi uzatmak değil.

UE’de: Anim Graph’ta state machine’in çıkışına Inertialization düğümü konur. UE 5.8’de bir de Dead Blending düğümü var — Epic’in kendi dokümanı ikisini karşılaştıran bir tablo veriyor (Epic: Blend Nodes). Dead Blending’i UE için yazan kişi Daniel Holden (Ubisoft La Forge) ve kendi blogunda gerekçesini anlatıyor.

Sayısal çapa: Epic’in tavsiyesi inertialization blend süresinin 0.4 sn’nin altında kalması (Epic: Transition Rules). Motion matching bağlamında Clavet’nin kullandığı değer 0.25 sn, yeniden tetikleme ölü bölgesi 0.2 sn (Clavet, GDC 2016). Dead Blending düğümünün Epic varsayılanları: Max Translation Velocity 500 cm/s, Max Rotation 360 °/s (Epic: Blend Nodes).

Uzaysal hizalama — Motion Warping

Motion Warping, karakterin root motion’ını dinamik olarak bir hedefe hizalamak için var (Epic: Motion Warping). Mekanizma üç parçadan oluşuyor:

  1. Montage içinde bir pencere — Notifies track’ine Add Notify State... > Motion Warping ile eklenen, başlangıç/bitiş zamanı olan bir bölge.
  2. Pencereye verilen bir isimWarp Target Name.
  3. Blueprint/C++ tarafında o isme bağlanan bir hedefAdd or Update Warp Target düğümü.

İsim ikisini birbirine bağlar; montage’daki isimle koddaki isim birebir aynı olmak zorunda.

Root Motion Modifier iki seçenek sunuyor:

  • Skew Warp — root motion’ı, pencerenin sonunda animasyonun konum ve rotasyonu hedefe denk gelecek şekilde yamultur. Merdiven ve mantle için kullanılacak olan bu.
  • Scale — animasyonun ölçeğini tek biçimli değiştirir.

Epic’in kendi örneği tam bizim vakamız: “bu mantle montage’ında, başlangıç warp bölgen karakterin elini engele koyduğu anı kapsamalı.”

Dikkat edilecek ayarlar:

  • Ignore ZAxis — Z bileşeninin warp’lanıp warp’lanmayacağı. Merdivende Z warp’ı gerekli, yani bu kapalı kalmalı.
  • Warp Translation / Warp Rotation — hangi bileşenin warp’lanacağı.
  • Rotation TypeDefault hedefin rotasyonuna eşleşir, Facing hedefe döner.
  • Warp Rotation Time Multiplier — rotasyonun pencereden daha hızlı tamamlanması için. Pencere 2 sn ve bu değer 0.5 ise rotasyon 1 sn’de biter.

Ön koşullar: Motion Warping eklentisi açık olmalı ve karaktere Motion Warping Component eklenmeli. Ayrıca kullanılan animasyonda Enable Root Motion açık olmalı.

Zamansal hizalama — Distance Matching

Distance Matching, animasyonu zamanla değil mesafeyle sürer (Epic: Distance Matching). Animasyondan bir Distance Curve üretilir; curve’ün x ekseni animasyonun pozları, y ekseni kat edilen mesafedir. Çalışma anında Anim Blueprint bu curve’de mesafe değerine karşılık gelen pozu bulup oynatır.

Epic’in kendi cümlesiyle sonucu: animasyon oynatma hızı karakterin hareket hızına uyacak şekilde sürülebilir, bu da animasyonların ince ayarlanma ihtiyacını azaltır ve karakterin hızı değiştiğinde animasyonu yeniden yapmayı gerektirmez.

Bu cümle önemli: ClimbSpeed’i değiştirdiğinde merdiven animasyonunun yeniden ayarlanması gerekmiyor demektir. His ayarını tasarımcıya bırakan mekanizma bu.

Kurulum zinciri:

  1. Animation Locomotion Library eklentisi açık olmalı.
  2. Animation Sequence’te Windows > Animation Data Modifiers > Add Modifier > Distance Curve Modifier ile curve üretilir.
    • Sample Rate30 çoğu vakayı karşılıyor.
    • AxisZ iniş animasyonları için, XY locomotion geçişleri için. Merdiven dikey olduğu için Z.
    • Stop at End — karakter son frame’den önce durabiliyorsa açılır.
  3. Uniform Indexable codec’li bir Curve Compression Settings asset’i oluşturulup animasyona atanır. Bu zorunlu — varsayılan sıkıştırmayla curve çalışma anında okunamaz.
  4. Anim Graph’ta Sequence Evaluator düğümü + üstünde bir Anim Node Function.

Üç düğüm var:

  • Distance Match to Target — hedefe kalan mesafeye göre poz seçer (iniş için).
  • Advance Time By Distance MatchingSequence Evaluator’ı karakterin her frame kat ettiği mesafe kadar ilerletir. Merdiven tırmanma döngüsü için kullanılacak olan bu.
  • Set Playrate to Match Speed — sabit hızlı hareket varsayımıyla play rate ayarlar.

Distance matching’in kendisi ayrı bir paftada anlatılıyor: Distance Matching — Start & Stop. Bu bölüm onun yerine geçmez; merdivene özel kullanımını (dikey eksen, Advance Time By Distance Matching) belirtir.

Motorun değiştirilemez gerçekleri

Bunlar tasarım tercihi değil, motorun davranışı. Prosedürün şeklini bunlar belirliyor.

En kritik gerçek — Walking ve Falling’de Z root motion yok sayılır

Epic’in root motion dokümanından, birebir: karakter Walking veya Falling durumundayken root motion’ın Z ekseni yok sayılır ve gravite uygulanır; karakter Flying durumundaysa root motion’ın tamamı uygulanır ve gravite yok sayılır (Epic: Root Motion).

Sonucu: root motion’la dikey tırmanma MOVE_Walking veya MOVE_Falling’de imkânsızdır. Animasyon ne kadar iyi olursa olsun motor Z’yi atar ve karakter yerinde sayar.

Bu, “root motion mu, hız değeri mi” sorusunu ikiye ayırıyor:

Soru Cevap
Hangi movement mode? Zorunlu: MOVE_Flying ya da MOVE_Custom. Seçenek değil.
Dikey ilerlemeyi ne sürüyor? Asıl tercih bu — ve ancak doğru mode’a geçtikten sonra anlamlı. Bkz. Tırmanma döngüsünü ne sürecek

Epic’in kendi topluluk eğitimi de tam bu yüzden MOVE_Custom’ı seçiyor ve montage’a kilitleme yöntemini gerekçeli olarak reddediyor: oyuncunun merdivende her an kontrolü koruyabilmesi (istediği an bırakma, atlama) gerekiyor (Epic Dev Community: Climbing Up! Ladders in Multiplayer).

Root Motion Mode ve performans bedeli

Anim Blueprint’in Class Defaults > Root Motion Mode seçenekleri: No Root Motion Extraction · Ignore Root Motion · Root Motion from Everything · Root Motion from Montages Only.

Performans uyarısı, Epic’in kendi metninden: Root Motion from Everything veya Root Motion from Montages açıkken Anim Graph, Worker Thread yerine Game Thread’de güncellenir. Game Thread’e binen ek yük performans sorunu yaratabilir (Epic: Root Motion).

Sonuç: root motion sınırsız kullanılacak bir şey değil. Doğru ayar Root Motion from Montages Only — yani root motion yalnız giriş/çıkış/mantle montage’larında çalışır, tırmanma döngüsünde çalışmaz.

Merdiven prosedürü

Sıra bağlayıcı. Her adım bir öncekinin çıktısına dayanıyor.

Adım 0 — Ön koşullar

  • AnimationWarping ve AnimationLocomotionLibrary eklentileri açık
  • Karaktere Motion Warping Component eklenmiş
  • Anim Blueprint Class Defaults > Root Motion Mode = Root Motion from Montages Only (bkz. Root Motion Mode ve performans bedeli)
  • Anim Graph’ta state machine çıkışında Inertialization düğümü (bkz. Poz sürekliliği — Inertialization)

Adım 1 — Merdiven aktörü ve algılama hacmi

Merdiven, tırmanılabilir bölgeyi temsil eden bir overlap hacmi taşır. Karakter hacimle örtüştüğünde “tutunabilir” bayrağı açılır; örtüşme bittiğinde kapanır.

Birden fazla hacimle aynı anda örtüşme mümkün olduğu için bayrak tek bir bool değil, hacim listesi olmalı; liste boşaldığında bayrak kapanır. Desen Epic’in merdiven eğitimi ve Nauja reposu ile aynı.

Hacim, merdivenin oyun düzlemindeki Y’sini taşır — Adım 3’te tutunma bu Y’ye snap’lenecek (bkz. 2.5D kilidi — Y ekseni disiplini).

Adım 2 — Movement mode

Tutunma anında SetMovementMode(MOVE_Custom, <Climbing>) ile custom moda geçilir ve PhysCustom içinde dikey hareket sürülür. Gerekçe: Walking ve Falling’de Z root motion yok sayılır.

MOVE_Flying de çalışır ve prototip için daha hızlıdır, ama Wall Slide ve Swing de aynı state makinesine oturacağı için custom mod uzun vadede doğru olanı.

Adım 3 — Giriş: üç ayrı vaka

Merdivene giriş Idle, Run ve Fall durumlarından mümkün. Bunlar tek bir giriş değil, üç ayrı vaka — her birinin kendi anchor’ı ve kendi montage’ı olur.

Vaka Tetikleyici Hizalama
Dipten Yerde, [F] Karakter merdivenin dip anchor’ına warp’lanır
Tepeden inme Yerde, üst platformda, [F] Tepe anchor’ına warp + gövde döner
Havadan yakalama Fall sırasında temas En yakın geçerli tutunma noktasına warp

Her vakada giriş montage’ına bir Motion Warping penceresi konur, Warp Target Name verilir, koddan Add or Update Warp Target ile hedef bağlanır. Root Motion Modifier = Skew Warp, Ignore ZAxis = kapalı (Z hizalaması gerekli).

Warp penceresi, elin basamağa değdiği anı kapsayacak şekilde ayarlanır — Epic’in mantle örneğindeki ilkenin aynısı (Epic: Motion Warping).

Adım 4 — Tırmanma döngüsü

Döngü root motion değil, Advance Time By Distance Matching ile sürülür: Sequence Evaluator, karakterin o frame kat ettiği dikey mesafe kadar ilerletilir. Dikey mesafe PhysCustom içinde ClimbSpeed’ten gelir.

Kurulum: tırmanma animasyonundan Axis = Z, Sample Rate = 30 ile Distance Curve üretilir; animasyona Uniform Indexable codec’li Curve Compression Settings atanır.

Kazanç: ClimbSpeed’i editörden değiştirdiğinde el/ayak basamağa oturmaya devam eder, animasyonu yeniden yapmak gerekmez (Epic: Distance Matching).

Adım 5 — Tepede çıkış (mantle)

Tepe çıkışı ayrı bir root motion montage’ıdır, döngünün devamı değil. Sırası:

  1. Kenar tespiti — ileri line trace ile kenarın bulunması
  2. Boş alan kontrolü — hedef konumda kapsül sığıyor mu (capsule trace); sığmıyorsa mantle tetiklenmez
  3. Warp hedefi = üst platformdaki duruş konumu, Skew Warp
  4. Montage oynatılır; root motion from Montages Only ile uygulanır (bkz. Root Motion Mode ve performans bedeli)
  5. Montage bitiminde MOVE_Walking’e dönülür

Animasyonsuz fallback: montage yoksa veya iptal edilirse karakteri hedefe taşıyan düz bir yol bulunmalı — aksi hâlde kenar tespiti başarılı olup hiçbir şey olmaz.

Adım 6 — Dipte çıkış ve zıplayarak bırakma

  • Dipte: zemine değince MOVE_Walking, state Grounded. Girdi varsa doğrudan hareket state’ine (tasarım kararı).
  • Zıplayarak bırakma: SpaceMOVE_Falling + duvardan uzağa küçük bir itiş. Hemen yeniden tutunmayı önlemek için kısa bir cooldown gerekir; yoksa karakter merdivene geri yapışır. Nauja reposu bu cooldown’ı açıkça uyguluyor.

Adım 7 — Kontrolün geri gelmesi

Her montage’ta oyuncunun kontrolü geri aldığı an açıkça işaretlenmeli — bir notify penceresiyle. İşaretlenmezse iki hata birden çıkar: oyuncu erken input verir ve “girdim yendi” hisseder; ya da montage bitmeden state değişir ve poz bozulur.

Kural (his katmanından): recovery’nin son frame’leri idle’a benzememeli, yoksa oyuncu ne zaman aksiyon alabileceğini okuyamaz.

2.5D kilidi — Y ekseni disiplini

Bu bölüm hiçbir kaynakta yok; düzlem kısıtının kendisinden türetildi.

Düzlem kısıtı normali (0, 1, 0), yani Y derinlik eksenidir ve oyun Y’de olmaz. Ama traversal’ın getirdiği her şey 3B’dir ve Y’ye sızar:

Sızıntı noktası Ne olur Ne yapılmalı
Root motion montage’ı 3B’de yazılmış klip yanal drift taşır; düzlem kısıtıyla kavga eder Montage’lar Y drift’i sıfır olacak şekilde üretilmeli; ayrıca warp hedefinin Y’si zorla düzleme sabitlenmeli
Warp hedefi Merdiven mesh’inin Y’si düzlemden farklıysa karakter merdivenin önünde/arkasında asılı kalır Add or Update Warp Target’a verilen konumun Y’si düzlem Y’siyle değiştirilir
Duvar/kenar trace normali Yüzey derinlikte birkaç derece eğikse normal saf ±X değildir Kuvvet ve yön oyun düzlemine projekte edilir
Mantle capsule trace Hedef nokta Y’de kayarsa boş alan kontrolü yanlış yerde yapılır Trace başlangıç ve bitişinin Y’si düzleme sabitlenir
bFacingRight Mesh 180° yaw dönüyor; sprite gibi flip yok Merdiven/duvar animasyonlarının mirror’ı ayrı iş kalemi

Aynı disiplin her traversal impulse’ı ve her warp hedefi için uygulanmalı.

Karar noktaları — his meselesi

Prosedür bu kararı kasten boş bırakıyor. Cevap teknik değil, tat meselesi.

Tırmanma döngüsünü ne sürecek

Seçenek Sonuç Bedeli
ClimbSpeed + distance matching (brifingin varsayımı) Hız kodda, editörden ayarlanır; basamak aralığı serbest Curve üretimi + Uniform Indexable sıkıştırma kurulumu gerekiyor
Saf root motion döngüsü Hız klibin içinde; el/ayak kusursuz oturur Basamak aralığı animasyona esir; ayrıca döngü boyunca Game Thread yükü (bkz. Root Motion Mode ve performans bedeli)

Öneri: birincisi. Gerekçe — his ayarını tasarımcıya bırakıyor (Zamansal hizalama — Distance Matching bölümündeki Epic cümlesi) ve level design’ı animasyona esir etmiyor. Ama karar tasarım tarafının.

Level design sözleşmesi — basamak aralığı

Araştırmanın en net çerçevesi: traversal level design’ı iki ayrı sözleşmeyle yönetilir ve karıştırılırsa proje batar (The Level Design Book, Metrics bölümü).

  1. Player metrics (fizik sözleşmesi) — karakterin ölçülebilir gerçekleri. Keşfedilir, tasarlanmaz: zıplama yüksekliği, hava süresi, yürüme hızı, kapsül boyu.
  2. Building metrics (bina sözleşmesi) — bu gerçeklerden türetilen kurallar: “merdiven modülü şu boyda”, “duvar bacası şu genişlikte”. Keyfîdir ama bir kez kararlaştırılıp yazıya dökülmelidir.

Distance matching seçildiğinde (Tırmanma döngüsünü ne sürecek kararı) basamak aralığı serbest kalır — çünkü animasyon mesafeyle sürülür, mesafe animasyonla değil. Yani üçüncü bir sözleşme doğmaz. Saf root motion seçilirse basamak aralığı animasyona esir olur ve o zaman “bir döngü kaç cm” sayısı hem animatörün hedefi hem level design’ın kısıtı hâline gelir.

Bu, tırmanma döngüsü kararının level design’a yansıyan yüzü. Karar yalnız kod tarafını değil, seviyelerin nasıl kurulacağını da belirliyor.

Rev Tarih Çizen Değişiklik
R-009 Alparslan İlk kayıt