Unreal Engine 4’te gerçek zamanlı dinamik kapak sistemi nasıl oluşturulur?

 Unreal Engine 4’te gerçek zamanlı dinamik kapak sistemi nasıl oluşturulur?
Okunuyor Unreal Engine 4’te gerçek zamanlı dinamik kapak sistemi nasıl oluşturulur?

Bir kapak sistemi, AI birimlerinin haritadaki çeşitli nesnelerin arkasına siper alarak doğrudan ateşten kaçınmasını sağlar. Bir kapak sistemi kullanmak, bir oyunun gerçekçilik seviyesini artırır ve her tür için temel taktik unsurları sunar. Bu tür sistemler iki farklı modülden oluşur: kapak oluşturma ve kapak bulma. Kapak oluşturma tipik olarak statiktir ve oyun başlamadan önce yapılırken, kapak bulma oyun sırasında gerçek zamanlı olarak gerçekleşir.

Bu makalede, Unreal Engine 4’te tamamen dinamik, gerçek zamanlı bir kapak oluşturma modülünün nasıl sıfırdan oluşturulacağını açıklayarak ve bir kapak bulma modülünün uygulanmasını sağlayarak kapak sistemlerinin statik doğasına meydan okuyorum.

Sağlam bir kapak sistemi oluşturmak ilk bakışta göz korkutucu görünebilir, ancak bunun sadece bir dizi basit tekniğin birbirine yapıştırıldığını anladığınızda, elinizdeki görev çok daha az göz korkutucu görünecektir.

İster yeni nesil gerçek zamanlı strateji (RTS) oyunu yapıyor olun, ister bunu birinci şahıs nişancı (FPS) oyununda kullanmak istiyorsanız, bu makaledeki bilgileri faydalı bulacağınızı umuyorum. Demo projesini indirmenizi ve bir araya getirildiğinde hepsinin nasıl çalıştığını kontrol etmenizi öneririm.

Proje, iyi yorumlanmış kaynak koduyla birlikte yukarıda tartışılan tüm tekniklerin tamamen işlevsel bir uygulamasını içerir.

Demo projesini ve kaynak kodunu indirin.

İçindekiler

Araçlar ve Ön Koşullar

Öğretici Unreal Engine 4 (UE4) sürüm 4.18’i kullanır, ancak motorun eski sürümleriyle de çalışmalıdır. Örnek proje ve kaynak kodu C ++ ile yazılmıştır. Örnek projeyi ve kaynak kodunu anlamak için UE4, C ++ ve UE4 Taslakları hakkında temel bir anlayışa ihtiyacınız var.

Tasarım

Bir kapak sistemi tasarlarken karşılaşacağınız en önemli üç zorluk aşağıdaki gibidir:

  • Veri üretimi
  • Veri kalıcılığı
  • Veri kullanımı

Bu makale, korumanın çalışma zamanında mevcut olabileceği veya tamamen ortadan kalkabileceği gerçek zamanlı dinamik bir kapak sistemi oluşturmaya odaklandığından, üçüne de optimize edilmiş bir yaklaşım uygulamak önemlidir.

İki veri oluşturma yöntemini ele alıyorum : navmesh kenar yürüyüşü ve 3B nesne taraması .

3B nesne taraması
Navmesh kenar yürüyüşü

Kapak verileriniz eşzamanlı olarak oluşturulursa, oyun performansınızda gözle görülür bir aksamaya neden olarak oyunda gecikmelere neden olur. Kapak verisi üretimini paralel hale getirmek için Unreal Engine’in mükemmel çok iş parçacıklı API’lerinden nasıl yararlanılacağını gösteriyorum, tipik olarak günümüz oyun donanımlarında bulunan çok çekirdekli işlemeden yararlanıyorum.

Benzer şekilde, kapsama verilerine erişim çok yavaşsa, oyununuz önemli miktarda yavaşlar ve kapak sorgularında büyük miktarda CPU ve / veya GPU döngüsü tüketir. Bundan kaçınmak için, uzamsal verilerin gerçek zamanlı eşzamanlı araması için tasarlanmış bir veri yapısı kullanmak en iyisidir : oktree . Sekizlerin uygun şekilde kullanılması, özel kapak verilerinin , örneğin örtü malzemesi (taşa karşı saman), yükseklik, sağlık vb. Hızlı ve verimli erişimle depolanmasına da olanak tanır .

Veri kullanım optimizasyonları – birimleriniz gerçek zamanlı olarak hangi kapak noktasının kullanılacağına aktif olarak karar verirken – raycast sayısını en aza indirin ve uzamsal arama olanaklarının (sekizler) kullanılabilirliğinin yanı sıra doğrudan getirme talepleri (diziler veya haritalar) için destek sağlayın .

Bir birimin ateş açmak için nasıl siperden çıkabileceğini öngörmek için, gözetleme veya eğilme yeteneklerinin haritasını çıkarmak gerekir Bir tank siperden dışarı bakamaz – bir piyadenin yapabileceği. Bunu çok fazla raycast kullanmadan gerçekleştirmenin bulduğum en iyi yolu, birimler üzerinde “eğilme ofsetleri” tanımlamaktır. Bunlar, kapaktan yapılan vuruş testi sonrasında ünitenin konumuna eklenen basit şamandıralar.

Son özellik, gerçek zamanlı dinamik güncellemelerdir – oyunda yeni bir nesne ortaya çıktığında, Unreal’ın olay sistemini kullanarak delegeler aracılığıyla onun çevresinde (ve içinde) koruma noktaları oluşturuyoruz. Bu, Tick için kaynakları israf etmememizi sağlar ve bu da, özen gösterilmezse oyunu önemli ölçüde yavaşlatabilir. Biz recast en navmesh kiremit güncelleme olayların içine kanca sadece gerektiğinde ilgili fayans ve güncelleme kapak noktaları.

Tüm tekno konuşmaya rağmen, aslında harika bir şekilde basit: birkaç önemsiz döngü ve UE4 belgelerinden birkaç eksik sayfa. Öyleyse hadi başlayalım.

Veri Oluşturma – İki Yol

Kapak verisi oluşturmak için birden fazla strateji var ve en önemli ikisini ele alıyorum: birincisi, 3B taramaya benzer bir teknik ve ardından bir navmesh kenar yürüyüş yaklaşımı.

3B nesne taraması, bir nesnenin çevresinde oluşturulan bir 3B ızgaraya dayanır. İşin büyük kısmını yapmak için genellikle her eksen için bir tane olmak üzere 3 ana for-loop’unuz vardır. Izgara üzerinde sabit bir mesafe olan noktalar üzerinde yineleme yaparsınız ve bir raycast ile herhangi bir şeye çarpıp vurmadığınızı kontrol edersiniz.

3D nesne taraması:

  • Kapak noktalarını kenar yürüyüşüne göre daha düzgün dağıtır
  • Navmesh ile uyumlu olmayan, ancak “kuvvet alanları” gibi bir kapak sağlayan nesneleri destekler
  • Minimum hata şansı vardır
  • Daha yavaştır (çok sayıda ızgara noktası nedeniyle)
  • Manzaralarla kötü başa çıkıyor

Navmesh tabanlı yaklaşım çoğunlukla navmesh verilerine dayanır ve nesnelerle kendi başına ilgilenmez: Haritadaki bir nokta herhangi bir navmesh poligonu tarafından KAPATILMIYOR ise, o zaman bu, koruma sağlayacak kadar büyük bir şey tarafından işgal edildiği anlamına gelir.

Navmesh kenar yürüyüşü:

  • Oldukça hızlı
  • Sağlam peyzaj topolojisini kolayca idare eder
  • Güç alanları ve benzerleriyle başa çıkamıyorum
  • Biraz daha hataya meyillidir: döşeme sınırları, uyumsuz noktalar
  • Kapatma noktalarını eşit olarak dağıtmaz

Bunları ilerledikçe daha ayrıntılı olarak ele alacağım, öyleyse hadi 3B nesne taramanın işine bakalım!

Nesne Tabanlı Kapak Noktası Oluşturma

Navmesh’i delikler için taramak yerine, nesnelerin kendilerini tararız. Bunu 3B’de bir nesneyi taramak gibi düşünün: X, Y, Z eksenleri boyunca dilimleyin, dilimleri bir ızgaraya böldünüz ve nesnenin çevresinin – veya 3B çevresinin – zeminle nerede buluştuğunu belirlemek için ışın yayınlarını kullanın. Bu aynı zamanda C-şekilleri, halkalar, kaleler gibi düzensiz şekilli nesneler için de işe yarar.

3D tarama ızgarası şuna benzer:

Turuncu işaretçiler, bir nesnenin içindeki ve çevresindeki 3B ızgara noktalarını temsil eder.

Bu, esasen, oyuncunun sınırlayıcı kutusunu 3 boyutlu bir ızgaraya bölen çok basit 3 döngü ile gerçekleştirilir. Ancak ızgarada birçok nokta var ve bazıları nesnemize yakın bile değil, bu yüzden onları filtrelemeliyiz.

Ve neden sadece bir 2D ızgara kullanmıyorsunuz, sorabilirsiniz? İki şey yüzünden:

  1. Çok katlı nesneler (çok katlı evleri düşünün)
  2. Eğimli zeminlerde döndürülmüş nesneler
Çok katlı bir navmesh.
Eğimli zeminde döndürülmüş nesne.

Geçersiz ızgara noktalarını filtrelemek için, en yakın yer düzlemine yeterince yakın olup olmadığını belirlemek için her noktadan -Z yönünde aşağıya bir ışın atarız. Eğer öyleyse, o zaman onu geçerli olarak işaretleriz ve bir sonrakine geçerek, sonunda her noktadan ışınları aşağıya atarız.

Neyse ki, raycasting çok ucuzdur, bu nedenle tek tek nesneler için endişelenmemize gerek yoktur – yalnızca çalışma zamanında çok sayıda nesneye sahip olduğumuzda sorun yaşamaya başlayabiliriz, ancak biz bu köprüyü geçerken orada ol.

Raycast’ler ile yer düzlemleri bulma.

Mavi: yere, altındaki ızgara noktasından daha yakın Kırmızı: zeminden aşağıdaki ızgara noktasından
daha uzak

Yalnızca mavi olanları sakladığımız için, bir sonraki geçişte endişelenecek çok daha az noktamız var: minimum zemin boşluğunu ve minimum kaplama yüksekliğini kontrol etmek.

Minimum zemin boşluğunun kontrol edilmesi.

Kırmızı: nesneye çok yakın
Yeşil: en küçük birimin altına sığması için nesneden yeterince uzak

Minimum kapak yüksekliğinin kontrol edilmesi.

Kırmızı: çok kısa
Mavi: yeterince uzun veya boş

Üst ortografik görünümden şu şekilde görünüyor:

Kırmızı: ızgara noktalarını engelleme; 
Yeşil: serbest ızgara noktaları

Nihayetinde aradığımız şey, navmesh üzerindeki kırmızı işaretlere en yakın noktalar. Bunlar, aşağıdaki beyaz işaretçilerin bir alt kümesiyle temsil edilir:

Navmesh üstte olacak şekilde.

Nihai koruma noktaları aşağıdaki mor işaretçilerle temsil edilir. Kırmızı işaretçileri (yukarıda) yineleriz ve navmesh’e düşen kırmızı işaretlere en yakın olan beyaz işaretçileri seçeriz:

Mor: son kapak noktaları

Nihai sonucumuz şuna benzer:

Mor: son kapak noktaları

Eğimli bir navmesh üzerinde ölçeklenmiş, döndürülmüş, çok katlı bir aktör şöyle görünüyor:

Çarpışma kutularına uyum düzeyine dikkat edin – navmesh yaklaşımı daha az uyumludur

Yukarıdaki resimlerden de görebileceğiniz gibi, bu teknik hem kapak nesnesinde hem de zemin düzleminde hem döndürmeyi hem de ölçeklendirmeyi destekler. Her tür geometri için uygundur ve artık sahneye elle tek bir işaretçi yerleştirmek için seviye tasarımcılarına sahip olmak zorunda değilsiniz.

Bu tür otomatikleştirilmiş nokta oluşturma, çok iş parçacıklı yürütme ile iyi oturduğundan, UE4’e iş parçacığı havuzuna koyması için talimat verdiğimiz zaman uyumsuz bir görev içindeki tüm mantığı loblayacağız. En iyisi, tüm bunlar kutudan çıkar çıkmaz motor tarafından destekleniyor!

Her tür oyuncuyla çalışmasını sağlamak için özel bir UActorComponent oluşturuyoruz ve 3D tarama görevlerimizi oradan oluşturuyoruz. Buna UCoverGeneratorComponent diyelim . Bu bileşeni herhangi bir güç alanı türü aktörlere ekleyin . Normal nesneler için kullanmayın – daha sonra özetlediğim navmesh tabanlı jeneratör, mükemmel çok amaçlı çözümümüz.

Navmesh Kenar Yürüyüşü

Ağır vuruş zamanı, örtme sisteminizin ihtiyaçlarının% 90’ını karşılayan jeneratör. Bu yüzden daha fazla uzatmadan, kenarı yürümeye başlayalım!

Kenar yürüme yoluyla örtü oluşturma aslında çok basit bir işlemdir: iki köşe alın, ortaya çıkan kenara her iki yönde dik bir ışın atın, ışının bir şeye çarpıp çarpmadığını görün ve eğer evet ise, o zaman siper bulduk.

Dikey ışınlar (sarı)

Çıkıntı veya uçurum duvarı algılamayı ekleyerek ışın sayımı açısından işleri daha da karmaşık hale getirebiliriz:

Çıkıntı algılama

Bununla birlikte, bu, her navmesh tepe noktası başına en az 4 ışın daha ekliyor, bu nedenle şimdi toplamda 6’dayız: dikey yer ışınları için 2, çıkıntı algılama için 4. Hatta daha ileri gidebilir ve bu güzel uçurum duvarları için eğim toleransı uygulayabiliriz, böylece manzaralar gibi sağlam topoloji düzgün bir şekilde taranır:

Çıkıntı toleransı iş başında.

Ancak bu, taraf başına en az bir ışın daha, bu da bizi en kötü senaryoda toplam 8 ışına çıkarıyor. Bu özelliğin projenizin performans maliyetine değip değmeyeceğine siz karar verirsiniz – Neslin çoğu zaten tam olarak eşzamansız olarak gerçekleştiği için açık bırakma eğilimindeyim ve oyun, kapak sistemi tüm bu süslü çıkıntıları incelemekle meşgulken bile başlayabilir. Ben bıraktım.

Adım 1 – Kenar algılama
Adım 2 – Nokta oluşturma

Hız

Birkaç kenarda yürümek, nispeten küçük bir nesneyi bile ızgara noktalarına dilimlemekten çok daha ucuzdur. Izgara noktalarının çoğunun size en az bir raycast’e mal olduğunu ve basit bir ağda bunlardan binlercesi olabileceğini düşünün. Sınırlayıcı kutu ne kadar büyükse, 3D tarama ile çalışmak o kadar pahalıdır.

Öte yandan, karmaşık bir nesnedeki navmesh polys sayısı birkaç yüzü geçmez, bu nedenle nesne istediğiniz kadar büyük olabilir. Sınırlayıcı kutusunun, navmesh çoklu sayısı üzerinde hiçbir şekilde etkisi yoktur. Nesnenizde çok fazla yürünebilir alan varsa, büyük olasılıkla birkaç polisle birleştirilecektir. Yüzeyde birçok dakika detayınız varsa, üzerinde gezinme bile olmayabilir. Ve bir canavar varlığı oluşturmayı başarsanız bile, navmesh çoklu sayısı, onu taramak için gereken 3B ızgara noktalarının sayısına kıyasla büyük olasılıkla soluk kalıyor.

Sağlam Peyzaj Topolojisi

Manzaralar, navmesh’lerin olduğu ve UE4’e entegre açık kaynaklı yol bulma uygulaması olan Recast’in parladığı yerlerdir.

Peyzaj topolojisi.

Manzaralar ve 3B nesne tarama yaklaşımı ile ilgili sorun, çoğu zaman kapak noktalarını amaçlanan kapak nesnesi yerine peyzaja ait olarak yanlış tanımlamasıdır. Navmesh tabanlı nesil kullanırken bu bir sorun değildir ve performans kazanımlarının yanı sıra bu tekniği neden elimizden geldiğince kullanmamızın ana nedenidir.

Kuvvet Alanları (Kalkanlar)

Bir güç alanı.

Kuvvet alanları, Recast’in geçmediği bir şeydir ve bu nedenle, 3B nesne tarayıcının tek gücüdür. Navmesh’i hiç etkilemeyen dinamik nesneler olduklarından, kapak noktası veri yapısında bir noktanın bunlardan birine ait olup olmadığını belirtmek için bir boole bayrağı oluşturdum. Demo projesinde sarı işaretlerle belirtilmiştir. Reinhardt’ın Overwatch’daki kalkanını düşünün, ancak hareket etmeyen bir kalkan. Bu, birimlerin içlerinden ateş ederken aynı zamanda düşman ateşinden korunmalarını sağlar.

Hatalar

Navmesh tabanlı yaklaşımın dezavantajları yoktur ve çoğu zaman bu, Recast’in döşeme sınırlarında görünen gereksiz kenarlarda kendini gösterir. Kapak oluşturma sırasında onları ayırmak dışında onlar hakkında yapabileceğimiz pek bir şey yok.

Navmesh üzerindeki fazla köşeler.

Gördüğünüz gibi, birkaç fazla köşe var, ancak bunların çoğu kapak noktası oluşturma sırasında atılıyor. Onlarla baş etmenin birincil yolu, ışınları kenarlarının XY eksenlerine dik iki yönde atmak ve bunu sabit bir yükseklikten yapmaktır. Hiçbir şey vurulmadıysa, o zaman bizim noktamız sadece bir kiremit sınırı tepe noktasıdır ve güvenli bir şekilde atılabilir. Bunlar nesnelerinize de nüfuz eder, ancak aynı ayıklama tekniği geçerlidir.

Diğer hata türü, Recast’in kapalı ve açık alanlar arasında ayrım yapmaması, yani katı nesnelerin içinde de bir gezinme oluşturması gerçeğinden kaynaklanır:

Katı bir nesnenin içinde Navmesh.

Bu açıkça bir işe yaramaz ve bunun üstesinden gelmenin tek yolu, haritanızda daha büyük katı ağlara sahip olduğunuz yerlere navigasyon değiştirici birimleri yerleştirmektir.

Bu, çoğunlukla doğru navmesh oluşturmaya neden olur. Ancak, bu iç gezinmeleri tamamen gizleyemeyeceğiniz durumlar olduğunu unutmayın. Yine de, kapak sistemimiz ulaşılamayan örtü noktalarını otomatik olarak filtrelediği için sorun değil, bu sadece küçük bir performans kaybına neden olacaktır. Navmesh yol bulma sorguları, kapak bulma kodumuzun geri kalanına kıyasla nispeten pahalı olma eğilimindedir, bu nedenle yine de ulaşılamayan navmesh adalarının sayısını en aza indirmeyi hedeflemelisiniz.

Gezinme değiştirici hacmi iş başında.

Ardından, uzamsal verilere hızlı ve optimize edilmiş erişim sağlayan bir veri yapısında kapak noktalarımızı nasıl saklayacağımıza bakacağız: oktree.

Veri Sürekliliği – Octree

Bir ahtapotu bir ağaçla geçmeye benzer: hayal etmesi kolay ama tırmanması zor. Oktree, “küpü 8 küçük küp halinde bölün, durulayın ve tekrarlayın” demenin süslü bir yolundan başka bir şey değildir. Benzer şekilde, bir dörtlü ağaç tam da budur – dört küçük kareye bölünmüş bir kare, bu da daha küçük dört kareye bölünmüştür, vb. Tüm kapak noktaları haritamızı bir oktree’de saklayarak, uzamsal sorgularımızın her zaman alabilecekleri kadar verimli olmasını sağlayabiliriz.

8 küçük küpe bölünmüş bir küp

İyi haber şu ki, UE4 tamamen işleyen bir oktree uygulaması içerdiğinden, işin çoğu bizim için Epic tarafından yapıldı. Kötü haber: neredeyse hiç belge yok. Korkmayın, çok karmaşık olmayacak ve Epic’in canavarlarını nasıl kullandığını görmek için her zaman FNavigationOctree’ye bakabiliriz .

Oktree’nin bir özelliği, mevcut veriyi ondan silmek istediğinizde, bir eleman kimliğini iletmeniz gerektiğidir. Ancak bu kimlikler oktree’de saklanmıyor – onlar için kendi depolama tesisimizi kurmalıyız.

FNavigationOctree’nin adımlarını takip ederek , basit bir TMap <const FVector, FOctreeElementId> Eleme ntToID kullanıyoruz; burada FV ector, bir kapak noktasının konumudur ve FOctreeEle mentId, Epic’in, öğenin bulunduğu düğüm ve dizini. Ayrıca haritaya yapılan tüm erişim çağrılarını iş parçacığı güvenli sarmalayıcı yöntemlerinde kapsıyoruz. Oldukça standart şeyler.

Oktree’mizin yarıçapı (boyutu) navmesh’lerimizinkini taklit etmelidir. Ancak basitlik uğruna, bunu sadece 64000 olarak ayarladık, bu aynı zamanda UNavigationSystem’in varsayılan olarak navmesh için dahili olarak kullandığı değerdir .

Gerçek Zamanlı Dinamik Güncellemeler

Kapak sistemimizin temel özelliklerinden biri, çalışma zamanında ortamdaki değişikliklere yanıt verebilme ve yeni geometriyi anında işleyebilme yeteneğidir.

Bu, ARecastNavMesh’i alt sınıflara ayırarak ve OnNavMeshTilesUpdated yöntemini geçersiz kılarak yaptığımız Recast’ın döşeme güncelleme etkinliğine bağlanarak gerçekleştirilir . Geçersiz kılınan yöntemin içindeki işlevsellik çok basittir, ancak vazgeçilmezdir: bir kutucuk her güncellendiğinde özel bir dinamik çok noktaya yayın temsilcisini bilgilendirin. Daha sonra ana teminat sistemi sınıfımız olan UCoverSystem’den (bir tekli) temsilciye abone oluyoruz ve buna göre kapak noktası oluşturucu görevlerini oluşturuyoruz.

Alt sınıfımıza AChangeNotifyingRecastNavMesh diyoruz ve onu özel bir oyun modu aracılığıyla oyuna bağlıyoruz . Oyun modu geçersiz kılar PostActorCreated () bildirilen yöntemini AActor ve kullanır ) SpawnActor ( bizim örneğini AChangeNotifyingRecastNavMesh olarak takip:

void ACoverDemoGameModeBase::PostActorCreated(){ Super::PostActorCreated();  GetWorld()->SpawnActor<AChangeNotifyingRecastNavMesh>(AChangeNotifyingRecastNavMesh::StaticClass());}

Tek bir olayda güncellenen birden çok döşeme olabileceğinden ve döşemelerin bazıları nispeten kısa bir süre içinde birden çok güncelleme alacağından, görev oluşturma mantığımızı aynı döşemeyi güncellememek için zaman dilimine ayırıyoruz. art arda iki kez.

Ayrıca Proje Ayarları ==> Navigasyon Sistemi ==> Aracılar ==> Desteklenen Aracılar’a gidip Navigasyon D ata K lası ve Tercih Edilen Gezinme Verilerinin her ikisinin de ChangeNotifyingReca stNavMesh olarak ayarlanması gereken yeni bir giriş eklemeniz gerekir. yani:

Desteklenen acenteler.

Ayrıca Navigasyon Sistemi altında Otomatik Navigasyon Verisi Oluştur seçeneğinin işaretini kaldırmanız gerekir :

Navigasyon verilerini otomatik oluşturun.

Yeni ayarların uygulandığını görmek için düzenleyiciyi yeniden başlatmanız gerekebilir.

Çarpışma Yapılandırması

Piyonlar ve araçlar gibi birimlerin etrafında örtü oluşturulmamalıdır, bu yüzden özel bir izleme kanalı tanımlayarak bunları dışarıda bırakalım. C ++ ‘da ECC_GameTraceChannel1 olarak başvurabiliriz .

Git Proje Ayarlar … ==> Motor ==> Col lision ve o tıklayarak n Yeni İz Ch frekanslarını … düğmesini.
Ad: nUnits Yok
Varsayılan Yanıt : Yoksay

Yeni bir izleme kanalı oluşturmak

Şimdi, İzleme Kanallarının altındaki Ön Ayar bölümünü genişletin ve yanıtlarını yeni oluşturulan NonUnits izleme kanalımıza göre ayarlamak için aşağıdaki ön ayarların her birine çift tıklayın . Aşağıda listelenmeyenleri olduğu gibi bırakın – zaten varsayılan olarak Yoksay’a ayarlıdırlar ve orada istediğimiz şey budur.

Üzerinde onay kutusunu işaretleyin Blok içinde NonUnits aşağıdaki tüm ön ayarları satır:

  • Hepsini engelle
  • BlockAllDynamic
  • Yok edilebilir
  • Görünmez Duvar
  • InvisibleWallDynamic
Çarpışma kurulumunu engelleme

Daha sonra, onay kutusunu işaretleyin Overlap içinde NonUnits aşağıdaki tüm ön ayarları satır:

  • Örtüşme Tümü
  • OverlapAllDynamic
Çakışan çarpışma kurulumu

Ardından, ” Kalkan ” veya ” Kuvvet Alanı ” adlı yeni bir Nesne Kanalı tanımlayın :

Özel çarpışma nesnesi kanalı

Ve son olarak, ” NonBlockingShield ” veya ” NonBlockingForceField ” adlı özel bir çarpışma Ön Ayarı oluşturun :

Özel çarpışma ön ayarı

Çalışma Zamanında Kapak Bulma

Artık, süslü küçük oktree’nizde kapak noktalarınız var ve her şey verimli ve çok iş parçacıklı, tüm döşeme güncellemelerinde geçen özel navmesh … Her şey yolunda, bu yüzden şimdi bu verileri kullanmaya başlama zamanı!

Birimleriniz, bir RTS yapıyorsanız, muhtemelen bir seferde düzinelerce birim aramak istiyor – daha iyisi, taktik ağırlıklı bir RTS (teknik olarak bir RTT) – peki buna en iyi nasıl yaklaşmalılar? Çok kolay: sadece oktree’yi sorgulayın, ihtiyaçlarına uygun bir nokta seçin, seçilen yeri ayırın ve oraya gidin.

Bir CoverFinder hizmeti veya görevi oluşturmanızı öneririm , ana sınıf UBTService veya UBTTaskNode olabilir . Bir göreve giderseniz, ona bir Cooldown dekoratörü ekleyebilirsiniz, böylece yalnızca her x saniyede bir çağrılır ve oktree ve navmesh’inizi sorgularla veya PhysX’inizi raycast’lerle doldurmaz.

Bunun yerine , UBTService için bir UCoverFinder hizmeti de oluşturabilirsiniz . Demo projesinde sizin için her iki sınıfı da oluşturdum, ancak sistemi kapak sorgularıyla spam yaptığımı * yapıyorum *, böylece davranış ağacınızdaki UCoverFinder tik aralığını daha az kaynak tüketecek şekilde ayarlamak isteyeceksiniz. senin oyunda.

Kapak Değerlendirmesi

Gerçek zamanlı kapak değerlendirmesi.

Siper bulucu, hedef düşman biriminden belirli bir mesafe arasındaki koruma noktalarını değerlendirir. Kapak demo projesinde bunlara sırasıyla minimum ve maksimum saldırı aralığı diyorum. Bulucu, kapsamı maksimum saldırı menzili olan sınırlayıcı kutu içindeki noktalar için oktree’yi sorgular ve ardından düşmana minimum saldırı menzilinden daha yakın olan noktaları filtreler. Buna ünitemizin optimum aralığı diyelim .

Daha sonra, aşağıdaki koşulların geçerli olduğu ilkini bulana kadar optimum aralığında kapak noktalarını yineler:

  • Birim, düşmanı doğrudan siperden vuramaz
  • Ünite dikizleyerek veya siperden dışarı doğru eğilerek düşmanı vurabilir
  • Düşmanın görüş hattı diğer birimler tarafından engellenmez
  • Ünite, navmesh üzerinde yol bulma yoluyla kapak noktasına ulaşabilir

Birliğimizin dikizleyerek veya siperden dışarı doğru eğilerek düşmanı vurup vuramayacağını kontrol etmek için, birimin eğilme (veya gözetleme) yeteneği parametresi tarafından yönlendirilen iki ray yayını kullanıyoruz. Bu, ünitenin konumuna, baktığı yere dik bir yönde eklenen basit bir şamandıra ofsetidir.

Siperden dışarı doğru eğilerek testi vurun. 
Sarı maviye vurmaya çalışıyor.

Açık mavi ok: Düşmanı öne doğru eğerek vuramaz
Turuncu ok: Eğilerek düşmanı vurabilir

Yukarıdaki ekran görüntüsünde, sarı bir birim, mavi birime güvenli bir şekilde çarpabileceği bir nokta belirledi, böylece mavi bir kapak için kapışırken karşılık gelen kapak noktasına hareket ediyor.

Sarı, güvenli bir kapak pozisyonu alır.

Ünitenin her iki tarafında kontrol iki kez yapılır: bir kez ayakta durma pozisyonundan ve başarısız olursa çömelmiş bir pozisyondan. Bu, en kötü durum senaryosunda 4 raycast ile sonuçlanır – ayakta: sol, ayakta: sağ, çömelmiş: sol, çömelmiş: sağ.

İyi bir nokta bulunana kadar her kapak noktası için aynı prosedür tekrarlanır ve sonuçta <kötü koruma noktaları & g t; x 5 ray yayını genel olarak.

Kuvvet alanları söz konusu olduğunda durum biraz farklıdır: Buradaki tek şart, birimin düşmanını doğrudan koruma noktasından vurabilmesidir. Diğer bir deyişle, yalın / dik kontroller yapılmaz, ancak gerekli olan fazladan bir kontrol vardır: ünite kalkanın içinden geçmelidir.

Bunun için kaputun altındaki Shield nesne kanalımızı kullanan özel NonBlockShield çarpışma ön ayarımızı kullanmalıyız . Yani, bu genel olarak 2 raycast ile sonuçlanır: biri NonUnits’e ve diğeri Shields’a karşı ve her ikisi de kuvvet alanı tipi korumanın kabul edilebilir olması için başarılı olmalıdır.

İstatistikler

Kapak sistemi, uygun bir şekilde STATGROUP_CoverSystem adlı kendi istatistik grubuyla birlikte gelir . Aşağıdaki bilgileri toplar:

  • Örtü bulmak için harcanan zaman (döngü sayacı)
  • Toplamda ortaya çıkan görev sayısına eşit olan FindCover’a yapılan toplam çağrı sayısı (dword)
  • Oyunda siper bulmak için harcanan toplam süre (float)
  • Kapak oluşturmak için harcanan zaman (döngü sayacı)
  • Toplam kapak oluşturma çağrı sayısı (hem uçta yürüme hem de 3d nesne taraması dahildir)
  • Teminat oluşturmak için harcanan toplam süre (her iki yöntemi içerir)
  • Etkin görev sayısı (dword)

Eylemde görmek için konsola stat CoverSystem yazın .

Profil oluşturma

Özel istatistikler ayarlandığından, kapak sisteminin profilini çıkarmak çok kolaydır. Sadece konsola stat startfile ve stat stopfile yazın ve Window => Developer To ols altındaki Session Frontend’i kullanarak oluşan günlük dosyasını görüntüleyin .

Profil oluşturma istatistikleri.
Profil oluşturma ayrıntıları.

Sonuç

Özetle, sağlam bir kapak sistemi, kapak oluşturma için iki ayrı teknik kullanır: 3B nesne tarama ve navmesh kenar yürüyüşü. İlki, kuvvet alanı tipi koruma (statik kalkanlar) için en iyisidir, ikincisi ise diğer her şey için (manzaralar, nesneler vb.) İyi çalışır.

Nesne tarama, aktörleri 3B ızgaralar halinde dilimlemeyi içerirken, navmesh kenar yürüyüşü, çıkıntı algılama için isteğe bağlı destekle mevcut navmesh polislerini bir alanı geçmek için alır.

Her iki teknik de verileri sekizli olarak depolar ve bu da verimli mekansal arama olanakları sağlar.

Gerçek zamanlı dinamik güncellemeler, Recast’in döşeme güncelleme etkinliklerine abone olarak ve zaman dilimleme ile etkinleştirilir.

Çalışma zamanında örtü noktaları bulma, birimler için “gözetleme” veya “eğilme” ofsetleri tanımlanarak daha çok yönlü hale getirilir.

Ray yayını sayısını azaltan çıkıntı algılamayı devre dışı bırakarak kapak oluşturma performansını artırabilirsiniz.

Navmesh tabanlı tekniğin en iyi şekilde çalışması için bazı ekstra adımlar atmalısınız, örneğin, navigasyon değiştirici birimlerini harita üzerinde, içinde gezinme bulunan daha büyük nesnelerin olduğu yerlere yerleştirmek gibi. Özel nesne kanalları, izleme kanalları ve çarpışmalar gibi bazı proje kurulumları da gereklidir.

Eminim şimdiye kadar benden yeterince aldınız, öyleyse neden demo projesini indirmiyorsunuz ve yukarıda tartışılan tüm tekniklerin tamamen işlevsel bir uygulamasını içeren kaynak kodunu araştırmıyorsunuz? Bir şey net değilse veya takılırsanız, aşağıdaki yorumlar bölümünde bana bildirmekten çekinmeyin!

Demo projesini ve kaynak kodunu indirin.

Dilerseniz Bir Sonra Ki Blog Sayfalarımıza Göz Atabilirsiniz..

Görüşmek Üzere Hoşçakalın WebOdasıyla Kalın..

Yorum Yap