leonscottkfm

Unreal MVP
31 May 2015
1,459
5
203
63
27
(34) İstanbul Avrupa
store.steampowered.com
Etrafınızdan çokça duymuşsunuzdur. Unreal Engine'de Blueprint var kod yazılmadan oyun yapılıyor böylelikle spagetti görüntüler, performans sorunları ve kötü oyunlar çıkıyor diye. Genellikle diğer oyun motorları ile karşılaştırıp böyle şeyler söylüyorlar.
Ben de size aslında Blueprinti tam anlamıyla kullanmayı bilmeyen insanların bunları söylediğini kanıtlayacağım.

1) Kod yazmak diye bir şey yoktur. Yazılım geliştirmek diye bir şey vardır. Bir yazılımı geliştirmek için illa geliştirme aracınızın metinsel olmasına gerek yoktur. Yani buna kod yazmak denecekse eğer, Blueprint de bir kod yazma aracıdır. Sadece görsel olarak yapıyor bu işi. Fakat kod bilmeyen insan Blueprint ile hemen oyun yapar algısı cahil insanların oluşturduğu bir algıdır. Piyasaya çıkan oyunların çoğu Unity ile çıkıyor. E peki herkes kod yazmayı mı biliyor ? Hayır. ChatGPT ye yazdırıp kopyala yapıştır yapıyorlar. Fakat aynısını blueprint ile yapamazsınız :) Öyle hemen bir paragraf görsel şey kopyalayayım gibi bir şey yok. Yapıştırdığınız gibi gelmez genelde. Variable oluşturamazsınız mesela. Fakat kodlama şeklinde çalışıyorsanız variable(değişkeni de) kod ile tanımladığınız için bu sefer kopyala yapıştır ile yapabilirsiniz.
Yani C++ ya da C# ile yapılan projelerde böyle tak çıkar daha kolaydır. Tam aksine hızlıca bir kod bloğuyla çalışabilirsiniz. Fakat bu kod bloğu başka .cpp dosyalarına erişim ve cast sağlıyorsa sıkıntı çıkar çünkü oralara da işlem yapmalısınız. Ayrıca Unreal denince akla Blueprint geliyor fakat Unreal'de isterseniz C++ ile çalışabiliyorsunuz ve C# den daha hızlıdır.

2) Performans sorununa gelecek olursak. Küçük ve orta ölçekli bir oyunda bu performans sorununu neredeyse görmezsiniz. Bu da optimizasyondan anlamayanların uydurduğu bir şeydir. Mesela piyasadaki oyunların çoğuna bakın bazı oyunlar var küçücük bir haritası var ve High ayarda 50fps zor alıyorsunuzdur. Fakat benim oyunumda mesela aynı kulvardaki oyunlara göre detaylı, foliage barındıran büyük bir harita var ve ben de 60 FPS verdiriyorum.
Zaten işlemci kullanımı da yok. Dolayısıyla kodlama ile ya da görsel programlama ile alakasız bir durum bu. Yapacağınız projelerdeki her türlü optimizasyonu gerçekleştirdiniz diyelim. İşin sonunda şunu göreceksiniz : Grafiği artırsanız da azaltsanız da aynı FPS yi alıyorsunuz.

İşte burası zurnanın zort dediği yer. Sebebi ise Material Draw Call problemi. Yani direkt olarak CPU problemi. Grafik ile alakası olmayan bir problemdir. Çünkü bir çoğumuz objeleri oradan buradan alıyoruz biraz nanite katıyoruz biraz reduce yapıp texture düşürüyoruz fakat çok efektif olmuyor.
Çünkü olay haritaya eklemiş olduğunuz objelerin yüzlerce farklı materiale sahip olmasıdır. Böyle olması ise işlemcide ve ekran kartında ekstradan bir hücre bloğu kaplanmasın sebep oluyor. Draw Call şişiyor ve performans sorunu oluşuyor. Yani siz grafiği artırsanız da azaltsanız da bir şey değişmiyor. Bunun çözümü ise Texture Atlastan geçiyor. Yani aslında kocaman bir otel var diyelim fakat içerisinde çeşitli objeler var ve bu oteli bir kişi modellemiş diyelim. Farklı farklı materialler yerine komple bir kaplama yapması gerekmekte. Sonradan değişmeyecekse komple bir kaplama yapmalı. UV yapılandırmasını buna göre ayarlamalı. Fakat genelde bağımsız yapımcılar olduğunuz için bazı alanlarda eksikleriniz oluyor mesela modelleme konusunda. Bu yüzden altından kalkabileceğiniz bir iş değil. Aynısını farklı motorda yaparsanız orada da düşük performans alırsınız. Hatta en güçlü bilgisayarınız ile eski bir oyun olan Garry's Mod adlı oyuna girin ve 100 obje spawnlayın FPS değerinizin nasıl düştüğünü göreceksiniz. Sebebi ise her objenin farklı farklı draw call yemesidir. Çünkü eski bir teknoloji olan motoru kullanmaktadır.

Grafik konusunda motorun ağır olma sebebi ise Render Pipeline'in güçlü olmasıdır. Unity adlı motorun Render Pipeline'i zayıftır. Çamur gibi grafikler ile projeye başlarsınız ve iyi bir render alabilmek için ya eklenti indirmelisiniz ya da düzenlemeler yapmalısınız. Yani zaten render kalitesi kötü olan motor daha iyi FPS verecektir. Fakat ileri düzey projelerde grafikleriniz çamur gibi bile olsa iyi grafikli bir oyundan daha az performans verebilirsiniz. Sebebi ise optimizasyon bilmemenizdir.

Peki kasan ve spagettiye dönen Blueprintler için ne yapılabilir? Öncelikle C# dosyaları da spagettiye dönebilir. 200 adet C# dosyası ile çalışmanız gerekebilir. Unrealde ise yine aynı şekilde .cpp dosyalarınızın sayısı 200 ü bulabilir. Olay olabildiğince az class tutmak ve aynı türden olan şeyleri tek bir yerden halledebilmekte yatıyor. Örneğin kapı kodladınız ve bu kapıdan 200 tane daha ayrı ayrı kodladınız. Bu çok mantıksız bir şeydir. Oysa ki tek bir kapı kodlayıp bunu Child edebilirdiniz. Ya da daha basitinden Tek bir kapıyı modular şekilde kodlayıp sadece 1 BP dosyası ile işi halledebilirdiniz.

Düşünsenize, ayrı ayrı kapılarınız var. Biri beyaz diğeri yeşil diğeri kırmızı hepsini ayrı ayrı kodlamışsınız. Açılması olsun vs. Bu beginnerların yapacağı bir şeydir.
Tek bir BP yapabilirsiniz. Enum liste göre spawn edilen kapıdan kapı seçimi yaparsınız , o seçenek için yazdığınız kodlar çalışır. Kırmızı seçince kırmızı kapı gelir mesela. Ya da Base bir kapı yapıp Child olanlarını oluşturursunuz.
Aynı şekilde her şeye Interact kodu yazmak yerine Blueprint Interface oluşturabilirsiniz. Bir kere Interact ile ilgili işlemleriniz belirtip sonra Interact edilecek BP lere bunu Implement edersiniz ve her BP de de özel kural belirleyip çalışmasını sağlayabilirsiniz. Örneğin kapıya Interact edildiğinde kilitli ise kilitli işareti gözükecek açık ise düz beyaz işaret gözükecek gibi. Fakat çekmeceye Interact edildiğinde direkt açılacak. Normal şekilde kod yazarsanız her biri için işlem yapmanız gerekirdi. Cast edip Linetrace atıp karmaşıklık oluşturacaktınız.

Fakat spagettiden kurtulmak için üç ana şey var Unrealde.

*Graphs: Siz genelde tek Graph üzerinde çalışıyorsunuz fakat isterseniz birden fazla Graph oluşturabilirsiniz. Örneğin tüm Equipmentler için bir Graph içinde çalışabilirsiniz. Tüm movement işlemleri için ayrı bir graph. Ana Graphta ise sadece Begin olayları ve Begin Tick işlemleri olur.
*Collapse Nodes: İşlemleri Graphlara ayırdınız fakat hala kod blokları çok fazla. Örneğin " Silahla ateş etme, Reload etme, Animasyonları, Sway özelliği, Efektleri" gibi çoğaldı gitti. Heh işte ilgili kısımları Commentler ile gruplandırıp Collapse Nodes yaparsanız onları da ayrı bir gruba alır. Örneğin Reload ile ilgili olan tüm kodları Commente aldınız Reloading Events yazdınız. Onu da komple seçip Collapse Nodes yaparsanız tek bir grup haline gelecek. Ona da Reloading yazın ve bir renk atayın. Böylece Silah graphının içerisinde > Reloading , Fire, Sway, Animations, FX gibi collapsed olmuş bölümler görürsünüz.
*Macro: Sürekli kullandığınız şeyler mi var ? Mesela sürekli yanlış olan şeylerde hata mesajı iletmek. Bunun kodunu bir kez yazıp sonra macro olarak atayın. Sürükle bırak ile istediğiniz yerde kullanırsınız.
Örneğin karakter bir işlem yaptığında sürekli canlı olup olmadığı kontrol mü edilmek isteniyor ? Bir macro yazın ve Isdeath koyun adını. İçerisinde de iki çıkış olsun. Branchten gelen True ve False çıkışları. Bunu istediğiniz yerde tekrar tekrar ek kod yazmadan kullanın.

Hareket kabiliyetlerimiz için Graphımız var. ( Movement Graph)
Equipmentler için Graph var. (Flashlight, Weapon, Healing) bunların içerisinde de Collapsed Nodeler var. (Reloading, Fire) (Heal Event, Heal Effect) gibi. Yakın zamanda bunları görsellerle açıklayacağım size.
Şimdilik bu şekilde ayak üstü yazdım fakat yakın zamanda detaylı ve görselli bir rehber hazırlarım. Böylece spagetti sorunundan kurtulacaksınız. Ayrıca spagetti sorunu sadece BP de olmuyor kodlamada da olur. Hem de daha beter olur çünkü her şey yazıdan ibaret. Gözünüz hiçbir şeyi göremez.
 
Son düzenleme:
  • Beğen
Tepkiler: nonlinear
Söylediklerinin büyük çoğunluğu doğru ama 1 noktaya parmak basmak istiyorum, cpp kopyala yapıştır ile olamıyor maalesef keşke olsa, sharp, java, html ile vibe coding oyunlar gördüm, hiç kodlama bilgisi olmadan adamlar çalışır oyun hazırlayabiliyor ancak unreal için durumlar çok farklı. AI baya element uydurarak kod blokları veriyor, şuralarda hata var diyorsun özür dileyip bir daha veriyor, tekrar hataları sayıyorsun özür dilemeye devam ederek saatler harcatıyor, ne zaman ki sen kodunu kendin yazıp burada şöyle bir sıkıntım var bunun çözümü nedir dersen hazır kodu analiz edip birşeyler yapabiliyor, dolayısıyla beklentinizi çok yükseltmeyin derim :)

Ayrıca extra küçük bir ekleme yapayım yazdıklarına " Circular Dependencies " bp tarafında daha töleranslı olduğu için 2 actor ün birbirinden referans almasına olanak tanıyabilir ancak bunu cpp de isteseniz de yapamazsınız. Dikkat etmeniz gereken durum illaki 2 actor birbirine bilgi göndermek zorunda ise, doğrudan cast değil, actor ref ile interface üzerinden göndermeniz gerekir ki ileride paketleme, yükleme, hatta infinite loop gibi sorunlar yaşamayın.
 
  • Beğen
Tepkiler: leonscottkfm