serhatwxe

Unreal MVP
3 Ocak 2016
317
1
54
28
(34) İstanbul Avrupa
Aşağıdaki bir AI_Task. Sahnede ise birden fazla Enemy_AI var, amacım bunlarla kim etkileşime girmişse onun lokasyonunu alması.
Sistem Offline'da çok iyi çalışıyor.
Fakat Online'da sadece Server'i oluşturan karakterin lokasyonunu alıyor. Client'i umursamıyor. Yani Client etkileşime girse bile Server'a gidiyor AI.
Sanırım bunun sebebi PlayerController ve Index 0 olması. Çünkü Index 0 yapınca Server, Index 1 yapınca Client, Index 2 yapınca Client 2'nin lokasyonunu alıyor. (PlayerController aynı bilgisayar üzerindeki farklı kullanıcıları temsil etse dahi ilk oraya takıldım fakat bununla da alakalı değil sanırım. index daima 0 olmalı gibi duruyor.) 
acaba farklı yerde farklı şekilde mi hesaplamalıyım? fikri olan

5da2ca70ac9ed761ac429b9e866823b74bc867ef.png
 
hocam aslında takıldığım yer orası değil de daha da başlangıcı. yani sanırım senin söylediğin perception algıladıktan sonra aynı kişiyi takip etmemesi için bir önlem.
ama benim sorunum bu değil. Enemy'i Client olarak da görüp etkileşime girsem, sadece Server'ı kovalıyor. Daima server yani. 
birkaç yerde konu açtım baya araştırdım, Behavior Task kısmında lokasyon hesaplama işlemini yapma, AI_Controller'da yap diyenler var.
ortaya çıkardığım son sonuç bu. bu hiç çalışmadı Hahaha
Bu arada hocam sen etkileşime giren Player'in lokasyonunu nasıl ve nerede hesaplıyordun, anlatma şansın var mı?

Photo-2.png


photo-3.png
 
Daima serveri kovalama işlemi index 0 ı baz alması ve onu da hafızadan silmemesi. Ancak serveri yok ettiğinde göreceksin ki bu seferde başkasını kovalıyor ve hafızası hep ona takılı kalacaktır. Başıma geldi çünkü. Karakterini destroy edersen en yakındaki oyuncuyu kovaladığın göreceksin. Ya da sistemi tam o şekilde yapmadıysan sen destroy olunca hiçbirinizi kovalamayaibilir.

Uzun olduğundan senin için video çektim biraz anlatarak ama ben de blackboard kısmından falan anlamıyorum pek. Ama bir şekilde yaptım üzerinde oynanırsa çok daha iyi olur. Bana basic bir şey lazımdı.


Bu içeriği görmek için üçüncü parti çerezlerine izin vermeniz gerekli.
Daha fazla detay için çerezler sayfasını ziyaret edin.

Mesela karakterin arkasından ona değen kişiye saldırmasını ise şöyle yapmışım. FollowNewActor diye hali hazırda bir fonksiyon yapmıştık zaten. Sphere koyumuşum collide olan oyuncu karakterine follow new actor diyip bağlamışım fonksiyonu




Stimulus olma kodu ise şöyle : Bu arada bunların bu son anlattıklarım AI event graphıyla ilgili



Pekiii gel gelelim görünen karakterin lokasyonunu nasıl alırız ? Hemen şöyle alabiliriz.



Yani o stimulus actor kısmından get actor location yaparsak o an stimulus olup taki edilecek actorun lokasyonu alınır.
Ayrıca orada Process Stimulu adlı bir macro var...





İşte o da bu. Sensed olduğunda new actore aktarılır oyuncu , izi kaybolduğunda lost olur. Tagı evilplayer değil ise AI onu umursamaz. Yani bir oyuncu karakterine saldırsın diğerini umursamasın istiyorsan özel olana EvilPlayer tagı girersen sadece EvilPlayer tagı olana saldırır.

Eğer bu sistemi yapamazsan bana yaz ben bilgisayarına bağlanır yapmaya çalışırım. Ve sen bu sistemi geliştirebilirsen yine bana haber ver.
Sistem basitçe server-client kim varsa Tagı EvilPlayer olan , onları görür ve kovalar hatta bir süre sonra hızlanır, onları kaybederse kaybedilen konuma kadar gidip orada araştırma yapar. Görürse tekrar kovalar. En yakındakine saldırmaya gider.


Yapay Zeka İle Testim Şurada :


Bu içeriği görmek için üçüncü parti çerezlerine izin vermeniz gerekli.
Daha fazla detay için çerezler sayfasını ziyaret edin.
 
1. Index senin durumunda daima sıfır olmalı. Diğerleri aynı bilgisayardaki diğer PlayerController ları temsil eder.
2. İlk gönderdiğin resimde KarakterNerede task ının içerisinde şöyle diyorsun "Bana bu bilgisayarda oynayan karakteri bul, lokasyonunu kaydet ve eğer bu bir monster karakter ise CanSeePlayer true olsun ". BehaviourTree sadece server da çalışıyor. Dolayısı ile o da senin söylediğini yapıyor. Sürekli serverda oynayan karakteri buluyor.
    "Kim etkileşime girmişse" kısmı ise hiç yok. Burada etkileşime girme ile ilgili kod yok. Kim oyuncuysa herhalükarda onu bul getir var. Sanırım yapmak istediğin şey "bu bilgisayarda kim oynuyorsa onu getir"  değil "Kim etkileşime girdiyse onu bul getire ve lokasyonunu al". O zaman Persecption sistemi ile "ALGILANAN" karakteri ve lokasyonun kaydetmelisin. Bunu da Task içinde yapmana gerek yok zaten. Perception component neredeyse orada yapacaksın.
3. İkinci postunda attığın OnTargetPerceptionUpdated metodunda bunu yapmaya çalışmışsın. Eğer doğru yapmış olsaydın oradaki ilk task a gerek te yoktu zaten. Burada ise "Algıladığım karakter 0_Base1 karakterse 0_Base1 değişkenimi doldur. Doldurduysan da dolduramadıysanda "ALGILADIĞIM HER NE İSE" onu iki BB değişkenine kaydet " diyorsun. Aslında burda yapmak istediğin bu olmaması lazım. Oradaki şey her şeyi algılamış olabilir. Sen sadece algılanan şeylerden "Karakter" olanı istiyorsun. Her algılanan şeyi değil.
4. 3 ncü postunda 0_Base1 in lokasyonunu BB değişkenine koyuyorsun ki yukarıda anlattığım gibi bu arkadaşın kim olduğu bile belli değil.
    
   Her türlü hesaplama server da yapılmalı. Zaten tüm sistem de bunun üzerine kurulu. Merak etme client karakterler da server da varlar. Ama GetPlayerCharacter sana oradaki oynayan oyuncuyu verir. İstediğin karakteri gidip bulmaz.
 
 
erginegider' Alıntı:
1. Index senin durumunda daima sıfır olmalı. Diğerleri aynı bilgisayardaki diğer PlayerController ları temsil eder.
2. İlk gönderdiğin resimde KarakterNerede task ının içerisinde şöyle diyorsun "Bana bu bilgisayarda oynayan karakteri bul, lokasyonunu kaydet ve eğer bu bir monster karakter ise CanSeePlayer true olsun ". BehaviourTree sadece server da çalışıyor. Dolayısı ile o da senin söylediğini yapıyor. Sürekli serverda oynayan karakteri buluyor.
    "Kim etkileşime girmişse" kısmı ise hiç yok. Burada etkileşime girme ile ilgili kod yok. Kim oyuncuysa herhalükarda onu bul getir var. Sanırım yapmak istediğin şey "bu bilgisayarda kim oynuyorsa onu getir"  değil "Kim etkileşime girdiyse onu bul getire ve lokasyonunu al". O zaman Persecption sistemi ile "ALGILANAN" karakteri ve lokasyonun kaydetmelisin. Bunu da Task içinde yapmana gerek yok zaten. Perception component neredeyse orada yapacaksın.
3. İkinci postunda attığın OnTargetPerceptionUpdated metodunda bunu yapmaya çalışmışsın. Eğer doğru yapmış olsaydın oradaki ilk task a gerek te yoktu zaten. Burada ise "Algıladığım karakter 0_Base1 karakterse 0_Base1 değişkenimi doldur. Doldurduysan da dolduramadıysanda "ALGILADIĞIM HER NE İSE" onu iki BB değişkenine kaydet " diyorsun. Aslında burda yapmak istediğin bu olmaması lazım. Oradaki şey her şeyi algılamış olabilir. Sen sadece algılanan şeylerden "Karakter" olanı istiyorsun. Her algılanan şeyi değil.
4. 3 ncü postunda 0_Base1 in lokasyonunu BB değişkenine koyuyorsun ki yukarıda anlattığım gibi bu arkadaşın kim olduğu bile belli değil.
    
   Her türlü hesaplama server da yapılmalı. Zaten tüm sistem de bunun üzerine kurulu. Merak etme client karakterler da server da varlar. Ama GetPlayerCharacter sana oradaki oynayan oyuncuyu verir. İstediğin karakteri gidip bulmaz.
 

Çok teşekkürler! Dediklerin kafama iyi oturdu.

leonscottkfm' Alıntı:
Bu içeriği görmek için üçüncü parti çerezlerine izin vermeniz gerekli.
Daha fazla detay için çerezler sayfasını ziyaret edin.

Burada aynı sistem sıfırdan yapılıyor. Tabi ben üstüne ekledim bir şeyler ama sen eklemeden bu şekilde de yapabilirsin. Sadece Memory Durationu 10 falan yapsan daha iyi olur.

Hocam hakkın yenmez, sayende yaptım. Benim sistem çok daha farklı ve karmaşıktı, dün tüm gün boyunca hepsini sildim. Buna rağmen hatalar vardı, az önce çözdüm tüm hataları. Ben çoğu olayı Behaviour Tree'de task oluşturarak hallediyordum, özellikle hesaplama işlemleri orada yapılmamalıymış. Videoyu izledim, kurduğum sistem videodakinden biraz daha karmaşık oldu (olmak zorundaydı) çünkü karakterin zıplaması, uzaklaşması falan vardı diye. Ama temelini senin yöntemlerine göre oluşturdum. Şimdi yapay zekayı geliştirme aşamasına geçiyorum.
Zaten en zor aşamalar bu yapay zekayı Replicated uyumlu yapmak. Çünkü bende birden fazla player + birden fazla yapay zeka var. Hepsi birbirine uyum içerisinde çalışmak zorunda.

Şöyle görüntü anlamında bi iki şey yaparsam çalışmamı paylaşacağım sizin görüşlerinizi de almak istiyorum.
Konu dışı ama, şu forum olmasa var ya işimiz çok zor.
 
Biraz daha yardımcı olmak açısından hep şöyle düşünmenizi tavsiye ederim:
Normal bir insana benzetelim.
  Behaviour Tree = Beyin, Akıl, veya mantık
  BlackBoard = Hafıza ya da kısa süreli hafıza
  Character = Vucut, Beden veya organlar.

 Nasıl ki gözlerimiz kulaklarımız burnumuz derimiz beyin için görüntü, ses, duyu vb. şeyler, bilgiler sağlıyor, kısa süreli hafızamız bu bilgilerin anında yok olmamasını sağlıyor ve beynimiz hafıza vasıtası ile aldığı bu bilgileri yorumlayıp sonuçlar ve kararlar çıkarıyor; öyle de oyun içerisinde Character imiz duyu organları vasıtası ile çeşitli bilgileri temin ediyor. Black board (Kısa süreli hafıza) ta kaydedilmesini sağlıyor. Behaviour Tree ise bu bilgiler üzerinde aynen beyin gibi çalışmak yorumlamak ve sonuçlara varmak zorunda. Vardığı sonuçlarla bendeni yönlendirme işine de sahip.

Bu benzetme ile düşünürseniz, normalde bilgi hep BT/BB ikilisinin dışından BB ye gelir. BT sürekli BB ye bakar ve gerekli akıl yürütmeyi yapar. 

(Basit te böyle başlayabilirsiniz. Sonrasında Service ler bu anlattığıma bir istisna teşkil ediyor çünkü.)
 
Services: Üzerinde bulunduğu ağaç yapısı aktif iken, ağaç hangi node u işletiyor olursa olsun arka planda sürekli yapman gereken işler kullandığın küçük programcıklardır. Örnek vermek gerekirse bir BT işliyor ve sen belli bir dalın tamamında sürekli "Sana en yakın düşmanın bulunmasını ve buna göre TargetEnemy BB değişkeninin doldurulmasını" istiyorsun. Çünkü o daldaki bir çok Task EQS ya da decorator un çalışması buna bağlıdır. Aynı şeyi aslında character in tick inde de yapabilirdik. Ancak Services kullanmak bize şu iki avantajı sağlar:
 1. Biz sadece o branch (dal)  aktif olduğunda bu hesaplamaların yapılmasını istiyoruz. Diğer dallar aktif olduğunda bu hesaplamaları istemiyoruz. Tick te yapsaydık bunu yapmak biraz daha zor olurdu. Service ler de bu otomatik. Eğer diğer branch a atlandıysa service otomatik kapanacaktır.
 2. Tick te BT yani AI sistemi ile alakalı olmayan bir sürü başka şey zaten olacaktır. AI ile alakalı şeyleri BT de service te toplamak hem characterimizin tick fonksiyonunu boşaltacaktır hem de aradığımızı daha organize şekilde bulup yönetebileceğizdir. Derli toplu olmak bu işlerde ki en önemli konudur.
İkinci bir örnek vermek gerekirse:
 Bir düşman düşünelim atak yapıyorken sürekli uygun bir sütre (cover) araması gerekiyor. Ateş etmediği ya da dinlendiği zamanlarda eğer canı yarımdan az ise kendi kendine health pack alması gerekiyor. Canı çok düşerse de geriye çekilip başka bir yoldan arkaya dolanmaya bu sırada da canını tamamlamaya çalışıyor.
  1. Sadece atak yaparken sütre arayan bir "Service" yazarsınız. Atak branch ında başka bir task ile de bu sütreye gitmeyi saklanmayı falan kodlarsınız. Geriye çekilmesi sırasında muhtemelen başka  bir branch çalışıyor olacaktır ve bu service çalışmayacaktır.
  2. Can azaldığında ve boş kaldığında kendi canını kontrol eden buna göre health pack kullanıp kullanmaması gerektiğini anlayan başka bir service yazarsınız. Bunu hem dinlendiği zaman branch ında hem de geri çekilme esnasında iki yerde kullanabilirsiniz.
  3. Bütün bunlar olurken Characterinizde  gereksiz yere AI ile ilgili kod olmaz. Orada başka şeyler daha kolay bulunabilir şekilde işler. AI ile ilgili her şey BT nizde tertipli düzenli olmuş olur.

Engine içerisinde hatırladığım 4 5 tane hazır her zaman kullanmak gerekecek yazılmış Service vardı. Ama isteyen istediği gibi service yazabilir. EQS query metoduyla yaptıramadığınız her türlü hesaplamayı Service lerle yapabilirsiniz. Sayısı size kalmış. 100 den fazla bile olabilir.
 
Peki şuradan örnek vermek gerekirse hangi kısımda service kullanılabilir ?

1-) AI Roam yapar etrafta dolaşır
2-) AI Karakteri görürse uzak mesafedeyse koşar dibine kadar geldiğinde yavaşlar
3-) AI Karaktere belli mesafedeyse vurur
4-) AI Karakteri kaybederse kaybettiği bölgede arama yapar
5-) AI Karakteri kaybettiği bölgede aramasını yaptıktan sonra daha uzaklara gidip oralara bakmayı tercih edebilir veya patrol pointine geri döner
6-) AI Karakterin canını belli bir miktarın altına düşürürse direkt ara sahne ile execution uygular
7-) AI Karakteri o an kovalıyorsa gerilim müziği çalar
:cool: AI Karakterin peşindeyse üzerinde kırmızı ışık belirir
 
Madde numarasına göre:
1. AI Roam: Bir kaç task yan yana. Yeni bir random lokasyon bul task ı. Bulduğun yere git task ı
2. Uzak mesafeden görmesi PawnSensing Component, BT de selector node ile reaksiyon, mesafelerin sürekli hesaplanması ve mesafeye göre karakter hızının ayarlanması  selectorda seçilen alt dalda Service. Yanına koşması yine aynı alt branch ta task.
3. Yine yukarıdaki madde de alt dalda yeni bir task vurması için. Yeterince yaklaşınca bir önceki maddede yapılan task biter ve vurma taskına geçer.
4. Karakteri kaybetmesi PawnSensing component, BT de Selector node ile reaksiyon gösterme, Arama bu selector altında bir başka branch. Bu branch ta son görülen yerin belirlenmesi taskı. Sonra gezinme için 1 nci madedeki gibi o alan içerisinde gezinme.
5. O bölgede yeterince arama yapıp yapmadığı ( Mesela zaman tutmak vb.) Arama branch ında bir Service olabilir. Service te yeterince karar verildiğinde Selector a geri dönüş ve 1 de ki branch a devam. Böylece patrol pozisyonuna geri dönmüş olur.
6. Bu AI lık yapılmasa daha iyi olabilir ama eğer yapılacaksa tüm BT de çalışan bir Service ile can kontrolü ona göre execution branch ına geçebilir.
7. Bence bunun AI ile ilgisi olmaması lazım. Ben bunu GameState ya da GameMode da yapardım. Eğer ille BT de olacaksa sadece bir task olurdu bu.
8. Bu da aynı şekilde bir task olabilir.
 
erginegider' Alıntı:
Madde numarasına göre:
1. AI Roam: Bir kaç task yan yana. Yeni bir random lokasyon bul task ı. Bulduğun yere git task ı
2. 8. Bu da aynı şekilde bir task olabilir.

Bir tık konu dışı ama konu konuyu açıyor. Hocam peki Cull Distance'in Multiplayer uyumu var mıdır? Misal haritanın bir bölmesinde X kişisi var, haritanın diğer noktasında da Y kişisi var. Cull Distance sayesinde bir obje, X kişisine gizleniyorsa, objeyle etkileşime giren Y kişisinin yaptığı eylem ve faaliyetler X kişi için uygun çalışır mı? 
Çünkü X göremiyordu, Server olsa bile.

Birkaç kişiye sordum bir sıkıntı olmaz, mesele sadece Visibility ile alakalı dediler, madem öyle millet neden NetCullDistance'e bulaşıyor?
Ayrıyeten World Partition meselesi var. Sisteme bunu entegre ettim fakat Multiplayer açısından bir sıkıntı yaşar mıyım ileride bilmiyorum. Multiplayer entegreli diyorlar ama mantıken bir takım sıkıntıların olması gerekiyor, genelde hep öyle olur çünkü :D
 
Kısaca CullDistance hakkında sordukların doğru söylemişler. O sadece oyun ekranı render edilirken kameranın bulunduğu konuma göre nesnelerin görünmesini ya da görünmemesini sağlıyor. Yani multiplayer ile olumlu ya da olumsuz herhangi bir alakası yok.
NetCullDistance ise tamamen farklı bir şey. Yine senin bulunduğun karakter/kamera lokasyonuna göre hangi aktörlerin replicate edilmesi gerektiğini ya da gerekmediğini ayarlıyor. Birisi gözümüzün görmesi ile ilgili bir şey ve net ile alakası yok. Ötekisi aktörlerin replicate edilmesi ile iligili bir şey. Birincisi bilgisayarımızın GPU/CPU yükünü hafifletebilmek için yapılmış bir şey. Diğeri internet bandwidth imizin tasarruflu kullanılması ile ilgili bir şey.
 
World Partition evet tam olarak Networking uyumlu. Ama her şey de olduğu gibi kullanmasını bilmek gerekiyor. Networking te sorun yaşamamak için "Streaming Sources" olayını iyi anlamış olmak gerekiyor. Oyun türüne göre bazı ayarlamalar yapmanız ya da bazı aktörlere Streaming Source Component koymanız gerekebilir.
 
NetCullDistanceyi küçük oyunlarda kullanmasak sıkıntı yaşar mıyız ? 2023 yılında olmamız dolayısıyla artık her evde 25 mbit üzeri internet bulunmakta. Avrupada ise 50mbit ve üzeri. Ayrıca 16mbit ve üzeri upload bulunmakta.
CPU ise ryzen 5 5600 den başlıyor.
Basit bir oyun yaptığımızda bize sıkıntı yaratabilir mi ? Mesela bir korku oyununda hiçbir şekilde NetCullDistance kullanmasak bir problem yaşar mıyız ?
 
Tamamen göreceli bir konu. Oyunun büyüklüğüne, replicated olan obje sayısına, replicated olan parametre sayısına oyunun hızına vb. bir çok şeye bağlı olarak değişir. Genel olarak böyle candy crash vb. tarzında bir oyun yapmıyorsan her durumda kullanmak gerekir düşüncesindeyim. Bu oyununda gerekmese bile bir sonraki oyununda gerekebilir ve her zaman kullandığımız şeyleri iyi bilmemiz lazım.