Zaten cevapları araştırdım ama pahalı fonksiyonları / hesaplamaları ele almak için en iyi yaklaşımı bulamadım.
Mevcut oyunumda (2B kiremit tabanlı bir şehir binası) kullanıcı binalar yerleştirebilir, yollar inşa edebilir. Bir bina bu kavşağa bağlı değilse, etkilenen binanın üzerinde bir "Yola bağlı değil" işareti açılır (aksi takdirde kaldırılması gerekir). Binaların çoğunun yarıçapı vardır ve birbirleriyle de ilişkili olabilirler (örneğin bir itfaiye, 30 kiremit yarıçapındaki tüm evlere yardımcı olabilir). Yol bağlantısı değiştiğinde de güncellemem / kontrol etmem gereken şey bu.
Dün büyük bir performans sorunuyla karşılaştım. Şu senaryoyu inceleyelim: Bir kullanıcı elbette binaları ve yolları da silebilir. Bir kullanıcı bağlantıdan hemen sonra bağlantıyı keserse , aynı anda birçok binayı güncellemem gerekiyor . İlk tavsiye biri iç içe döngüler (kesinlikle bu senaryoda büyük bir nedenidir) önlemek için olacağını düşünüyorum ama kontrol etmek zorunda ...
- Bir yol döşemesinin kaldırılması durumunda bir bina hala kavşağa bağlıysa (bunu sadece o yoldan etkilenen binalar için yapıyorum). (Bu senaryoda daha küçük bir sorun olabilir)
yarıçap çinileri listesi ve yarıçap içinde binalar olsun (iç içe döngüler - büyük sorun!) .
// Go through all buildings affected by erasing this road tile. foreach(var affectedBuilding in affectedBuildings) { // Get buildings within radius. foreach(var radiusTile in affectedBuilding.RadiusTiles) { // Get all buildings on Map within this radius (which is technially another foreach). var buildingsInRadius = TileMap.Buildings.Where(b => b.TileIndex == radiusTile.TileIndex); // Do stuff. } }
Tüm bunlar FPS'imi bir saniye boyunca 60'tan neredeyse 10'a indirir.
Ben de yapabilirdim. Fikirlerim şöyle olurdu:
- Bunun için ana iş parçacığı (Güncelleme işlevi) değil başka bir iş parçacığı kullanılmıyor. Birden çok iş parçacığı kullanmaya başladığımda kilitleme sorunları ile karşılaşabilirim.
- Çok sayıda hesaplamayı işlemek için bir kuyruk kullanmak (bu durumda en iyi yaklaşım ne olurdu?)
- Daha fazla hesaplama yapmaktan kaçınmak için nesnelerimde (binalarda) daha fazla bilgi tut (örneğin yarıçaptaki binalar).
Son yaklaşımı kullanarak bunun yerine bu foreach formunda bir yuva kaldırabilirsiniz:
// Go through all buildings affected by erasing this road tile.
foreach(var affectedBuilding in affectedBuildings) {
// Go through buildings within radius.
foreach(var buildingInRadius in affectedBuilding.BuildingsInRadius) {
// Do stuff.
}
}
Ama bunun yeterli olup olmadığını bilmiyorum. Cities Skylines gibi oyunlar, oyuncunun büyük bir haritası varsa çok daha fazla bina ile başa çıkmak zorundadır. Bunları nasıl ele alıyorlar ?! Tüm binalar aynı anda güncellenmediğinden bir güncelleme kuyruğu olabilir.
Fikirlerinizi ve yorumlarınızı dört gözle bekliyorum!
Çok teşekkürler!