leonscottkfm

Unreal MVP
31 May 2015
1,493
5
213
63
28
(34) İstanbul Avrupa
store.steampowered.com
Unreal Engine içerisinde Behavior Tree gibi Stateler mevcut.
Ya da Animation Blueprint içerisinde yine State Machineler mevcut.
Fakat normal movement için böyle şeyler yok. Enum kullanmak zorundasınız ya da boolean cehennemine giriş bileti alacaksıız. Fakat her ne kadar enum kullansanız da boolean cehennemini tadacaksınız.
Şimdi şöyle bir durum var:

Benim oyunumda bir ton özellik var.

Movement
(
*Walking Running ve Idle tamamen Blendspace ile yönetiliyor ve oyuncunun hızına göre değişiyor.
*Crouching (Klasik Crouch-Uncrouch fonksiyonu ile çağırılıyor)
*Injured (Oyuncunun can değeri %50 altında ise injured moduna geçiş yapılıyor)
*Sitting (Oyunun ilk sahnesinde oturma özelliği var)
)

State
(
Aiming
Flash Aiming
Reloading
Busy (Obje incelerken ve görev yaparken oyuncunun diğer durumlara geçişini engellemek amacı ile yapıldı. Tüm geçişleri engelliyor. eğilme,koşma,silah değiştirme.)
)

Equipment
(
Flashlight
Compass
Handgun
Objective Item
)

Şimdi gördüğünüz gibi oyuncunun silah kullanma , el feneri kullanma, objektif eşyası taşıma gibi özellikleri var. Bunun yanı sıra bir de bunların alt iterasyonları var. Örneğin silah var mı ? varsa silah aim modunda mı ? Aim modundaysa ateş et.
Fener var mı ? Varsa aim modunda ve açık mı ? Açıksa Sol mouse tuşuna basılınca UV aktif et yoksa normal ışıklandır.
Bunlar hem diğerlerine geçişte hidden olacak ve diğer geçiş visible olacak hem de bazıları eğilirken kullanılamıyor ya da yaralıyken. Örneğin görev eşyası taşırken equipment değiştirirseniz eşya drop olur. Fakat eşya alırsanız öncelikle elinizdeki equipment none olur ve eşya elinize gelir. Çünkü inspect yapacaksınız dolayısıyla silah cebe geri girmeli. Ya da fener.

Ayrıca compass eğilirken kullanılabilirken, silah ve flash kullanılamaz. Injured modda compass kullanılırken silah ve flash kullanılamaz fakat objektif eşyası carry olabilir yani ele alınıp taşınabilir.

Şimdi bunların animasyon boyutu halledildi ve bunların hepsi boolean cehenneminde yönetiliyor. Fakat enuma geçerseniz işi kolaylaştıracağınızı sanıyorsunuz fakat orada da farklı bir cehennem mevcut. Merkezi Switch sistemi yaptınız diyelim. Crouch özelliğini set ettiniz. Geçmiş olsun. Animasyon çoktan set edildi fakat siz injuredde olduğunuz için eğilemiyorsunuz. Fakat öncesinde set edildiği için animasyon oynadı bile. Orada da ayrı kontrol gerekebilir.
Enum değiştirme işleminin başına branch koyup kontrol edeyim derseniz bu sefer de diğer özellikler de bu kontrole toplu tabii tutulacakları için onlar da çalışmayacak.
Enum sistemini ikiye ayırayım (EquipmentEnum ve CurrentEquipmentEnum) yapayım derseniz bu sefer baştaki enumu kontrol için kullanıp diğerini set edip diğerini kullanmanız gerekiyor. Fakat bu sefer de her işlemin kendi içinde booleanları yine olacak.

Örneğin Crouch set edilmeden önce is injured? is busy? is sit? bilmem ne kontrol edilecek.
Ayrıca hap kullanma durumu da var mesela eline hap al E basınca kullan Ya da Arkadaşın yakındaysa E bas hapı ona ver gibi.

Bu durumun içinden nasıl çıkılabilir ? Bir fikri olan var mı bu konuda ? Unreal buna bir kolaylık sağlamıyor çünkü. Ya bin tane boolean yapacaksınız ya da iç içe enumlar ile booleanlar yapıp merkezi sistem koyup beyin patlaması yaşayacaksınız.
Booleanlar kullanırsanız adam hızlıca switch yaparsa aynı anda ele fener ve silah gelme durumu var. Ya da birden koşarken silah seçti diyelim hem aim alır hem koşmaya başlar. Oysa ki biz koşarken aim alınmasını istemiyoruz.
Timer koyarsanız performans yok olur.
Enum koyarsanız birden fazla flag ve iç içe enum yapmanız gerekir.
Hem silah sistemini enum yapacaksınız hem stateleri enum yapacaksınzı hem de oyuncunun o anki durumlarından bazıları enum bazıları boolean olacak. Çünkü keskin geçiş olmayan şartlı durumlar var. Örneğin injured modda compass kullanımı gibi. Ve injured mod walking ile birlikte çalışan bir şey. Yani injuredken koşabiliyorsunuz.
Fakat siz Idle-Walk-Run durumunu enuma ekleyip alta da injured eklerseniz bu sefer injuredken run durumuna geçemezsiniz.

Yani her durumda bir sıkıntı yaşanıyor. Çünkü Bunu çözebilecek bir sistem mevcut değil.


1762095411951.png

1762095424480.png


1762095447030.png
 
Son düzenleme:
Şimdi cevabı doğrudan senin sisteme göre veremem ama genel olarak ben nasıl hazırlıyorum ondan bahsedeyim (replicated logic dahil)

Öncelikle ana state ler için Enum, -> Unarmed, Pistol, Rifle, Axe .... neler lazımsa
2. enum detay -> Injured, flashlight, injured+flashlight .... yine neler lazımsa
3. Aim -> X,Y

bir interface üzerinden AnimBP pawn tarafında replicated olan bu değerleri, Ana state de silah mı var -> Aim interface üzerinden çek, yoksa pas geç.

State ler arasında geçiş yapmak için AnimBP de Enum switch kullanabilirsin.

Walk-Run-Jump-Crouch bunları Skip owner olarak replicate ederek, localde hareketi verip server üzerinden skip owner bool değerleri gönderebilirsin.

Uzun lafın kısası çok temel hareketler klasik boolean, geri kalan herşey enum ile çözülebilir ki genelde çözüm hep bu yönde birçok projede
 
Aslında bu problemler her projede az çok olan şeyler. Bu yüzden de tabii ki çözümler var. GAS sistemi bunun için yapılmış bir sistem mesela. "Gameplay Tag" ler genel olarak enumlardan bool lardan kurtulmak için bir çözüm olarak geliştirilmiş. Animation Layer sistemi de değişik aletlere ya da durumlara göre Anim graphın bir parçasını tamamen değişmesini sağlayrak state işlevini gereksiz hale (daha az gerekli diyeyim) getiriyor. Böylece graph çok karışık ve komplex olmuyor. Mesela tabanca nın üst vucut animasyonu tabanca item ın dan geliyor, tüfek animasyonu tüfekten geliyor ve uygun yerde diğer şeylere karışmadan çalışıyor. Bunun haricinde Anim node lardan "Alias" ve "Conduit" da bu geçişleri basitleştirmek için bir yöntem. Birden fazla durumdan bir yere geçiş gerekiyorsa alias kullanmak sorunu çözüyor. Bunun haricinde "interface" ler var "event dispatchers" lar da yerine göre bu problemlerin çözülmesine katkı sağlıyorlar. Eğer daha aşağı normal kod sistemine girersen "virtual fonsiyonlar" (Polymorphism) de oyunda bizi bool lardan enum lardan kurtarır. Mesela her item ın ayrı bir "Use" fonksiyonu yaparsak virtual olarak, her itema özel kendi "Use" fonksiyonunu yazabileceğinden, hiç if lere enumlara bool lara gerek kalmadan bir çok konuyu halledebiliyorsun. Bunların hepsi ayrı ayrı çok uzun olduğundan ayrıntıya girmiyorum.
Bu konular için en iyi örnek "Lyra" örneği. Orada yukarıda bahsettiğim herşeyin uygulama olarak yapılmışı var.
 
Son düzenleme: