AI temsilcileri ortamları hakkındaki bilgilere nasıl erişir?


9

Bu biraz önemsiz bir soru olabilir, ama bunu anlamakta güçlük çekiyorum. Yardımınız için çok minnettar olurum.

Nesneye yönelik tasarım kullanarak oyun geliştirmede, AI-ajanlarının eylemlerini gerçekleştirmek için oyun dünyasından ihtiyaç duydukları bilgilere nasıl eriştiklerini anlamak istiyorum.

Hepimizin bildiği gibi, oyunlarda AI ajanlarının sıklıkla 'çevrelerini algılamaları' ve çevrelerinde olanlara göre hareket etmeleri gerekir. Örneğin, bir oyuncu oyuncuyu yeterince yaklaşırsa kovalamak, hareket ederken engellerden kaçınmak (Engellerden Kaçınma direksiyon davranışını kullanarak) vb. İçin programlanabilir.

Benim sorunum, bunu nasıl yapacağımdan emin değilim. Bir AI aracısı oyun dünyası hakkında ihtiyaç duyduğu bilgilere nasıl erişebilir?

Olası bir yaklaşım, ajanların ihtiyaç duydukları bilgileri doğrudan oyun dünyasından talep etmeleridir.

GameWorld adında bir sınıf var. Önemli oyun mantığını (oyun döngüsü, çarpışma algılama, vb.) Ele alır ve aynı zamanda oyundaki tüm varlıklara referanslar tutar.

Bu sınıfı Singleton yapabilirim. Bir ajanın oyun dünyasından bilgiye ihtiyacı olduğunda, onu doğrudan GameWorld örneğinden alır.

Örneğin Seek, oyuncuya yakın olduğunda bir oyuncu programlanabilir . Bunu yapmak için ajanın oyuncunun pozisyonunu alması gerekir. Bu yüzden sadece doğrudan talep edebilirsiniz: GameWorld.instance().getPlayerPosition().

Bir ajan ayrıca oyundaki tüm varlıkların listesini alabilir ve ihtiyaçları için analiz edebilir (hangi varlıkların yakın olduğunu veya başka bir şeyi anlamaya): GameWorld.instance().getEntityList()

Bu en basit yaklaşımdır: Temsilciler doğrudan GameWorld sınıfına başvurur ve ihtiyaç duydukları bilgileri alırlar. Ancak bildiğim tek yaklaşım bu. daha iyisi var mı

Deneyimli bir oyun geliştiricisi bunu nasıl tasarlar? "Tüm varlıkların bir listesini alın ve ihtiyacınız olanı arayın" yaklaşımı naif midir? AI temsilcilerinin eylemlerini gerçekleştirmek için ihtiyaç duydukları bilgilere erişmesine izin vermek için hangi yaklaşımlar ve mekanizmalar vardır?


Bir GDCVault aboneliğine erişiminiz varsa, 2013 yılında AI bilgi modellerine ayrıntılı olarak giren "Hitman Absolution'ın Yaşayan, Nefes Atan Dünya için AI Yaratmak" adlı mükemmel bir konuşma yapıldı.
DMGregory

Yanıtlar:


5

Açıkladığınız şey, dünyayı sorgulamanın klasik bir "çekme" modeli. Çoğu zaman, bu, özellikle temel AI (en çok olan) oyunlar için oldukça iyi çalışır. Ancak, olumsuz olabileceğini düşünmeniz gereken birkaç nokta vardır :

  • Muhtemelen iki kat daha fazla tampon yapmak istiyorsunuz. Konuyla ilgili oyun programlama modellerine bakın . Verileri her zaman doğrudan dünyadan talep ederek, sonucun AI'nin hangi sırayla çağrıldığına bağlı olduğu garip yarış koşullarını elde edebilirsiniz. Bunun oyununuz için önemli olup olmadığını belirlemeniz sizin için. Olası bir sonuç, oyunu "ilk" veya "son" olana önyargıya çevirerek çok oyunculu haksız hale getirmesidir.

  • Toplu iş istekleri, özellikle belirli veri yapıları için genellikle çok daha verimli olabilir. Burada engelleri aramak isteyen her AI aracısının bir "sorgu nesnesi" oluşturmasını ve bunu merkezi bir engel singletonuna kaydetmesini sağlayabilirsiniz. Daha sonra, ana AI döngüsünden önce, tüm sorgular veri yapısına karşı çalıştırılır, bu da engel veri yapısını önbellekte daha fazla tutar. Daha sonra AI parçası sırasında, her aracı sorgu sonuçlarını işler, ancak artık doğrudan yapmasına izin verilmez. Çerçevenin sonunda, AI nesneleri sorguları yeni konumlarıyla günceller veya ekler veya kaldırır. Bu veri odaklı tasarıma benzer .

    Bunun temel olarak sorguların sonucunu bir arabellekte saklayarak çift tamponlama yaptığını unutmayın. Ayrıca, daha önce çerçeveyi sorgulamanız gerekip gerekmediğini tahmin etmenizi gerektirir. Bu bir "push" modelidir, çünkü aracılar ne tür güncellemelerle ilgilendiklerini beyan eder (karşılık gelen bir sorgu nesnesi yaparak) ve bu güncellemeler kendilerine gönderilir. Bir sorgu için tüm sonuçları depolamak yerine, sorgu nesnesinin bir geri arama içermesini de sağlayabileceğinizi unutmayın.

  • Son olarak, muhtemelen başka bir yerde iyi belgelenmiş olan miras yerine aranabilir nesneleriniz için arayüzler veya bileşenler kullanmak istersiniz. Bir liste üzerinde yineleme Entitiesdenetimi instanceOfmuhtemelen oldukça kırılgan kodu için bir reçete, sen de istiyorum dakikadır StaticObjectve MovingObjectolmaya Healable. ( instanceOftercih ettiğiniz dilde arayüzler için çalışmadığı sürece .)


5

Yapay zeka maliyetli olduğundan, performans genellikle mimaride itici faktördür.

Veri erişim modelleri hakkındaki endişelerinizi hafifletmek için, oyun endüstrisinin içinde ve dışında, insan navigasyonundan bize en tanıdık olana kadar uzanan birkaç farklı AI örneğini ele alalım.

(Her örnekte tek bir genel mantık güncelleştirmesi varsayılmaktadır.)

  • A * en kısa yolHer AI, yol bulma amacıyla haritanın durumunu hesaplar. A * her YZ'nin yol bulması gereken tüm (yerel) ortamı zaten bilmesini gerektirir, bu nedenle harita engelleri ve alanı (genellikle bir 2D boole dizisi) hakkında bilgi vermeliyiz. A *, en kısa yol açık grafik arama algoritması olan Dijkstra Algoritmasının özel bir şeklidir; bu tür yaklaşımlar yolu temsil eden listeler döndürür ve her adımda AI, hedefine ulaşana veya yeniden hesaplama gerekinceye kadar (örn. bir harita engel değişikliği nedeniyle) adım atmak için bu listedeki bir sonraki düğümü seçer. Bu bilgi olmadan gerçekçi en kısa yol bulunamaz. A *, RTS oyunlarındaki AI'ların her zaman A noktasından B noktasına nasıl gideceğini her zaman bilir - bir yol varsa. Her bir yapay zeka için en kısa yolu yeniden hesaplar, çünkü yol geçerliliği, daha önce hareket etmiş (ve muhtemelen belirli yolları bloke etmiş) AI'ların konumuna dayanmaktadır. Yol bulma sırasında A * 'nın hücre değerlerini hesapladığı yinelemeli süreç, matematiksel yakınsamadır. Son sonucun, görme duyusu ile karıştırılmış bir koku duygusuna benzediğini söyleyebiliriz, ancak hepsinde zihniyetimize biraz yabancıdır.

  • İşbirlikçi difüzyon Oyunlarda da bulunur, bu en çok gazların ve partiküllerin difüzyonuna dayanan bir koku hissine benzemektedir. CD, A * 'da bulunan maliyetli yeniden işleme sorununu çözer: Bunun yerine, tek bir harita durumu depolanır, tüm AI'lar için güncelleme başına bir kez işlenir ve sonuçlara her bir AI tarafından sırasıyla kendi hareketini gerçekleştirmesi için erişilir . Artık bir arama algoritması tarafından döndürülen tek bir yol (hücre listesi) değildir; daha ziyade her AI, işlendikten sonra haritayı inceler ve bitişik hücrenin en yüksek değere sahip olduğu yere taşınır. Buna tepeye tırmanma denir . Bununla birlikte, harita işleme aşaması zatenburada tüm AI gövdelerinin konumlarını da içeren harita bilgilerine önceden erişebilirsiniz. Bu nedenle, harita AI'lara ve ardından AI'lar haritayı referans alır.

  • Bilgisayarla görme ve yeniden yayınlama + en kısa yol Gezici ve drone robotik sistemlerinde bu, robotun hareket ettiği alanların kapsamını belirlemek için bir norm haline geliyor. Bu, robotların, ortamın tam hacimsel bir modelini oluşturmasına izin verir, tıpkı görüş veya ses veya dokunuşla (kör veya sağırlar için) yapacağımız gibi, robot daha sonra minimum topografik bir grafiğe (biraz ara nokta grafiği gibi) A * içeren oyunlarda kullanılır), daha sonra en kısa yol algoritmaları uygulanabilir. "Vizyon" acil çevre için bir ipucu sağlayabilir iken Bu durumda, hala sonuçlanırsonuçta hedefe giden yolu sağlayan bir grafik araması. Bu insan düşüncesine yakın: Yatak odasından mutfağa ulaşmak için oturma odasından geçmeliyim. Onları daha önce görmüş ve boşluklarını ve portallarını bildiğim gerçeği, bu hesaplanmış hareketi mümkün kılıyor. Bu, sert silikon yerine yumuşak proteine ​​gömülmüş de olsa, en kısa yol algoritmasının uygulandığı bir grafik topolojisidir.

Gördüğünüz gibi, ilk ikisi çevreyi bütünüyle zaten bilmeye güveniyor. Bu, bir ortamı sıfırdan değerlendirmenin maliyeti nedeniyle, oyunlarda yaygındır. Açıkçası, sonuncusu en güçlü olanıdır. Bu şekilde donatılmış bir robot (veya her karede derinlik arabelleğini okuyan bir oyun AI) önceden bilgi sahibi olmadan herhangi bir ortamda yeterince gezinebilir. Tahmin edebileceğiniz gibi, bu aynı zamanda yukarıdaki üç yaklaşımın en pahalısıdır ve oyunlarda bunu genellikle AI başına temelinde yapmayı göze alamayız. Tabii ki, 2D'de 3D'den çok daha az maliyetlidir.

Mimari noktalar

Yukarıda, AI için yalnızca bir doğru veri erişim modeli kabul edemeyeceğimiz açıktır; seçim neyi başarmaya çalıştığınıza bağlıdır. GameWorldSınıfa doğrudan erişmek kesinlikle standarttır: size dünya bilgisi sağlar. Temel olarak veri modelinizdir ve veri modelleri bunun içindir. Singleton bunun için iyi.

"tüm varlıkların bir listesini alın ve ihtiyacınız olanı arayın"

Bu konuda hiç naif bir şey yok. Saf olabilecek tek şey, gerekenden daha fazla liste yinelemesi yapmaktır. Çarpışma tespitinde, arama alanını azaltmak için örn. Dörtlü kullanarak bunu önleriz. AI için de benzer mekanizmalar uygulanabilir. Birden fazla şey yapmak için aynı döngüyü paylaşabiliyorsanız, bunu yapın, çünkü dallar pahalıdır.


Cevabın için teşekkür ederim. Oyun geliştirmeye yeni başladığımdan beri şimdilik basit "oyun dünyasından bir liste al" yaklaşımına sadık kalacağım :) Bir soru: sorumu GameWorldsınıfa referanslar içeren sınıf olarak tanımladım tüm oyun varlıkları ve ayrıca önemli 'motor' mantığının çoğunu içerir: ana oyun döngüsü, çarpışma algılama, vb. Temelde oyunun 'ana sınıfı'. Sorum şu: Bu yaklaşım oyunlarda yaygın mı? 'Ana sınıfınız mı var? Yoksa onu daha küçük sınıflara ayırmalı ve 'varlık veritabanı' nesneleri olarak bir sınıf var mı?
Aviv Cohn

@Prog Bir şey değil. Yine, yukarıdaki AI yaklaşımlarında (veya bu konuda başkalarının), "oyun dünyasından bir liste al" ın herhangi bir şekilde, şekil olarak veya biçimsel olarak yanlış olduğunu öne süren hiçbir şey yoktur . AI mimarisi AI ihtiyaçlarına uygun olmalıdır; ancak bu mantık, önerdiğiniz gibi modüler hale getirilmeli, (kendi sınıfında) daha geniş uygulama mimarinizden uzaklaştırılmalıdır . Evet, bu tür sorular ortaya çıktığında alt sistemler her zaman ayrı modüllere ayrılmalıdır. Yol gösterici ilkeniz SRP olmalıdır .
Mühendis

2

Temelde bilgi sorgulamak için 2 yolu olurdu.

  1. AIState değiştiğinden, bir çarpışma tespit ettiğinizde veya önemli olan nesneye yapılan bir başvuruyu önbelleğe aldığınızda. Bu şekilde hangi referansa ihtiyacınız olduğunu bilirsiniz. Ne zaman diğer sistemlerde büyük aramalar her kareyi çalıştırmak zorunda ben birden fazla arama yapmak zorunda değilsiniz onları kapalı domuzcuk tavsiye ederim. Dolayısıyla, bir düşman 'uyarısı' yapan bölge ile 'çarpışma' tespit edildi, eğer ona henüz bu nesneyi kaydettiren bir mesaj / olay gönderir ve oyun durumunu içinde bulunduğundan işini yapan birine değiştirir. o oyun kasası. Değişiklik yapmanızı söyleyen bir tür etkinliğe ihtiyacınız var, sadece bu bilgiyi vermek için kullandığınız geri aramaya bir referans gönderirim. Bu sadece oyuncu ile uğraşmaktan daha uzatılabilir. Belki bir düşmanın başka bir düşmanı veya başka bir nesneyi takip etmesini istersiniz. Bu şekilde, yalnızca tanımladığınız etiketi değiştirmeniz gerekir.

  2. Bu bilgilerle, size bir yol vermek için A * veya başka bir algoritma kullanan bir yol bulma sistemine bir sorgu gerçekleştirirsiniz veya bunu bazı yönlendirme davranışlarıyla kullanabilirsiniz. Belki ikisinin veya her neyin bir kombinasyonu. Temel olarak her ikisinin dönüşümü ile düğüm sisteminizi veya navmesh'inizi sorgulayabilmeli ve size bir yol verebilmelisiniz. Oyun dünyasında yol bulma dışında pek çok şey var. Sorgunuzu yalnızca yol bulmaya gönderirdim. Ayrıca, birçok sorgunuz varsa, bu şeyleri toplu yapmak muhtemelen en iyisidir çünkü bu oldukça yoğun olabilir ve toplu işlem performansa yardımcı olacaktır.

    Transform* targetTransform = nullptr;
    EnemyAIState  AIState = EnemyAIState::Idle;
    void OnTriggerEnter(GameObject* go)
    {
       if(go->hasTag(TAG_PLAYER))
       {
       //Cache important information that will be needed during pursuit
       targetTransform = go->getComponent<Transform>();
       AIState = EnemyAIState::Pursue;
       }
    }
    
    void Update()
    {
       switch(AIState)
       {
          case EnemyAIState::Pursue:
           //Find position to move to
           Vector3 nextNode = PathSystem::Seek(
                              transform->position,targetTransform->position);
           /*Update the position towards the target by whatever speed the unit moves
             Depending on how robust your path system is you might want to raycast
             against obstacles it can't take into account or might clip the path.*/
            transform->Move((nextNode - transform->position).unitVector()*speed*Time::deltaTime());
            break;
        }
     }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.