omer.hatay

Üye
2 May 2019
182
14
18
26
(34) İstanbul Avrupa
Merhabalar. Bir Grid sistemi oluşturuyorum. 150 ye 150 lik altıgenlerden oluşan bir sistem. Bu 150x150 olma durumu tabi şu anlık böyle. Mesela ben 1000x1000 yapmak istersem 2 adet iç içe for döngüsü kullandığım için motor hata veriyor ve "Sonsuz döngü algılandı diyor". Şimdi ilk olarak ben bu sistemin her bir karesini (aslında her bir altıgenini) bir "Actor" olacak şekilde ayarladım. Daha sonrasında bir kanaldan görüp "Add Instanced Static Mesh Component" kullanarak bir sistem oluşturdum ki onda da oluşturduğum meshler hakkında bir bilgiye ulaşamadım ve uzun vadede o sistem bir işime yaramayacaktı. Sonrasında gidip Static Mesh Actor oluşturup bundan bir grid sistemi oluşturdum şu an aklımda kalan tek soru, en performanslı hali bu mu yoksa daha iyisi var mı? 
haeirlu.png
 RESİM
 
Motorun sonsuz döngü olayını anlaması şöyle: Örneğin 1.000.000 işlemden yapınca bir tickte sonsuz döngüdeymiş olarak algılıyor. Bunun önüne geçmek için gridleri minecrafttaki gibi chuncklara böl ve her tikte atıyorum 10-15 chunk ayarlansın. Böylece sonsuz döngü olayını çözersin.

Her bir grid bir aktör ya da mesh olacaksa sorun büyük. oyun oynarken sahnende kaç grid gözükecek tahmini? 5-10 bin ise 5-10 bin draw call olacak demektir. Bu gridi hangi amaçla kullanacaksın? 

Eğer görsel birşeyse instanced static mesh olarak ekle. yalnız add instanced static mesh component demeyeceksin. Tek bir aktörde tek bir tane add instanced static mesh component diyeceksin. Sonra her bir grid icin bu componenti çağırıp add instance diyeceksin. Böylece tüm bu görüntü 5-10 bin drawcall yerine 1 drawcall olacak.

Eğer bu grid aktöründe bir fonsiyon falan varsa yine aktör olarak spawn et(Tick kullanmıyorsan ticki kapalı tut) ama sadece static meshi üstteki gibi başka aktörde instance olarak yarat. Eğer üstüne gelince renk değişimi falan oluyorsa tek bir instanceyi değiştiremezsin sabittir bunlar materyal olarak. O zaman şöyle yap:

Mesela üstüne gelince instanced static mesh componenti çağırıp o değiştirmek istediğin instanceyi sil ve static mesh component spawnla ve yapmak istediğini yap. Tekrar eski haline dönerken de static mesh componenti gizle ya da yok et ve tekrardan o nokta için bir instance ekle.

Draw call ve performansı optimize tutup da aynı zamanda interaktif bir grid yapmanın yolu bu.

Eğer gridi yol bulmak için falan kullanacaksan bunu vektör arrayları üzerinden de yapabilirsin

(Grid derken her bir kare demek istemiştim yazmış bulundum artık.)
 
Sağolun Hocam. İlk okuduğumda ne demek istediğinizi anladım ama nasıl yapacağımı oturtamadım. Sonra yavaş yavaş bir şeyler canlandı. Denedim. Birkaç kere daha okudum. Sistemin son geliştirmesini yapıyorum. İlk denememde silmesi gereken indexteki elemanı silmiyor onun yerine rastgele bir yerdekini siliyordu. Ben öyle zannediyordum. Meğerse Instanced Static Mesh Componentten bir nesneyi silince ondan sonra gelen bütün nesnelerin index değerleri bir eksiliyormuş. O index değerlerini yeniden nasıl ayarlayabileceğimi çözmem gerekiyor şu anlık. Çünkü yeni oluşturduğum bir nesneyi istediğim iki değer arasına koyamıyorum. Index değerini otomatik olarak sona atıyor. Bu da her yeni oluşturduğum birim için neredeyse gridin yarısının yeniden hesaplanmasını gerektiriyor ama böyle bir şeye gerek olmayacağını düşünüyorum. Bir şekilde o da çözülecektir.
 
Aynen bir indexi sildiğinde o index arrayı shrink ediyor yani boşalan indeksi silip sonraki gelen indexleri 1 azaltıyor. O yüzden birden fazla şeyi doğru şekilde for each ile silemiyorsun. Ben şöyle yaptım: diyelim ki 14 tane nesneyi silmem gerekiyor. Bu 14 nesneyi for each yapıp her biri için get component bounds deyip sonra instanced static mesh'te remove instance diyorum. 14 defa ayrı ayrı çağırılıyor ve indexi hep doğru buluyor. 

O meshi bulmak için indexini kaydedip çağırmıyorum. Onun yerine o meshin konumunu ve boyutlarını alıp o noktadaki meshleri bul ve sil diyorum. O noktada 1 tane mesh olacağı için 0. array elementini al ve sil diyorum.


 
Bugün çalışmaya başladığım instanced static mesh componenti denemekten vazgeçip normal actor le devam edeyim dedim. Sonra sizin yazdığını görüp bir de sizinkini deneyeyim dedim. İlk başlarda yapamadım. Sizinkini direk kopyalamaya çalıştım. İşime yarayacak kısımları almaya çalıştım. Ama benim farklı kullanmam gereken fonksiyon varmış. Get Instances Overlapping "Box" yerine "Sphere" kullanmam gerekiyor. Çünkü benim sistemimde her bir birim altıgen. Gittim onu denedim, o da işe yaramayınca kodu bir kaç kez gözden geçirdim. Çünkü silmesi gerekeni değil, yanı başındakini siliyordu. Meğersem Get Instances Overlapping Sphere fonksiyonunda istenen radius değerini biraz küçültmem gerekiyorki başka componentlerle etkileşime girmesin. Teşekkür ediyorum hocam değerli vaktinizi ayırdığınız için.
 
UE5 e bakıyordum geçenlerde. Nanite nasıl işliyor, draw call nasıl etkileniyor diye. Nanite etkinleştirdiğin static meshler tek draw call da çağırılıyor ve değişiklik olmadıkça tekrar draw call çağırılmıyor. 7-8 çeşit static meshi foliage ile tüm haritaya 500k kadar spawn ettim. Draw call 78 di. Sen de nanite ile instanced static mesh olmadan daha performanslı şekilde yapabilirsin. Meshte saydam bir materyal varsa nanite desteklemiyor. Tamamen opak ve tek taraflı materyaller için geçerli.