Jak wdrożyć „świadomość” wroga jednostek?

12

Używam Unity3d do opracowania prototypowej gry hybrydowej RTS / TD. Jakie jest najlepsze podejście do „świadomości” między jednostkami a ich wrogami? Czy to normalne, że każda jednostka sprawdza odległość do każdego wroga i atakuje, jeśli znajdzie się w zasięgu?

Podejście, które zamierzam teraz, to mieć kulę wyzwalającą na każdej jednostce. Jeśli wróg wejdzie na spust, jednostka dowiaduje się o nim i rozpoczyna sprawdzanie odległości. Czy to oszczędza trochę niepotrzebnych kontroli?

Jaka jest tutaj najlepsza praktyka?

Phil
źródło
Powinienem dodać, że liczba jednostek / wrogów będzie w skali Najwyższego Dowódcy
Phila

Odpowiedzi:

10

Spójrz na graniczne hierarchie woluminów (BVH). Są one najczęściej używane w wykrywaniu kolizji w celu zmniejszenia liczby kontroli potrzebnych podczas obliczania kolizji lub podczas renderowania w celu wykonania wygładzania elementów na obiektach. Ponieważ już używasz kul, sugerowałbym drzewo kuli, chociaż inne woluminy, takie jak AABB, mogą być bardziej wydajne. Nie jestem pewien, jakie wsparcie ma Unity dla takich rzeczy, jakich nigdy nie użyłem, ale prawdopodobnie jest coś w tym już w wykrywaniu kolizji lub renderowaniu części silnika.

Zasadniczo chciałbyś zgrupować wrogów, którzy są blisko siebie, w wielu sferach rodzicielskich. Gdy jednostka zostanie przeniesiona, sprawdzasz, czy jej sfera wyzwalająca jest skierowana na sferę macierzystą, zamiast sprawdzania każdego wroga. Jeśli kula wyzwalająca przecina się ze sferą macierzystą, sprawdziłbyś każdego wroga wewnątrz. Jeśli nie, możesz odrzucić wszystkich znajdujących się w nim wrogów. Chcesz ustawić wiele poziomów kul w oparciu o maksymalny rozmiar kuli lub liczbę wrogów dla każdej kuli i wykonać sprawdzenie na podstawie kuli najwyższego poziomu. Następnie chodzi tylko o zejście z drzewa, aby sprawdzić każdego wroga bez konieczności przeprowadzania kontroli odległości dla każdego z nich.

Wymagane kroki dla każdej ramki:

  1. Rusz wrogów
  2. Odbuduj / zaktualizuj BVH dla nowych pozycji wroga
  3. Poruszaj jednostkami i sprawdzaj na drzewie kuli.

Może to zmniejszyć liczbę koniecznych kontroli, gdy jest wielu wrogów, ale narzut związany z aktualizacją i przechowywaniem drzewa może nie być tego wart, gdy nie ma ich zbyt wielu. Nie znam Najwyższego Dowódcy, żeby wiedzieć, czego szukasz, więc zakładam, że „setki”. Musisz się profilować w różnych sytuacjach, aby dowiedzieć się, czy narzut będzie dla Ciebie tego wart.

Joel Baker
źródło
3
+1 to podejście będzie najprostsze, choć będzie zawierało pewne błędy. OP może chcieć to zaimplementować, a następnie zaimplementować coś w rodzaju oktetu. Ponadto w większości RTS jednostki reagują z pewnym opóźnieniem. W rzeczywistości większość sztucznej inteligencji w grach jest obliczana na 10-30 klatek na sekundę, przy czym gra może działać z prędkością 30-60 klatek na sekundę (liczby są oczywiście przybliżone).
Samaursa,
Dziękuję, właśnie tego potrzebowałem, aby pójść o krok dalej. Sprawdzę BVH i jak go wdrożyć w Unity. Bardzo pedagogiczny i pouczający post! +1
Phil
Aha i sprawdź Supreme Commander, jeśli jesteś w RTS. To naprawdę bardzo fajna gra, podobnie jak wszystkie gry Chrisa Taylora.
Phil
7

Nie ma potrzeby implementowania BVH, ponieważ silnik kolizji Unity już to robi.

Wystarczy założyć dużą ograniczający-Sphere spust do każdej jednostki (reprezentującego jego zakres) i obsłużyć OnCollisionEnter()i OnCollisionExit()zwrotnych, aby śledzić, które wrogowie są w zasięgu każdego urządzenia.

Zwróć uwagę, że interesuje Cię przypadek, gdy inna jednostka zderza się z kulą, a nie kiedy inna jednostka zderza się z kulą.

BlueRaja - Danny Pflughoeft
źródło
1
Myślę, że należy to zmienić na przynajmniej nieco powyżej zaakceptowanej odpowiedzi. Zaakceptowana odpowiedź jest dobra do nauki, ale ta odpowiedź powinna być na górze, ponieważ jest to najbardziej praktyczny sposób.
Varaquilex
Wierzę, że masz na myśli OnTriggerEnter()i OnTriggerExit()prawda?
Jibb Smart,
1

Innym rozwiązaniem, które skaluje się bardzo dobrze i które można wykorzystać do wielu innych rzeczy, jest mapa influeunce. Wygeneruj zestaw płytek siatki wokół urządzenia, aby skanować w promieniu X. Zeskanuj te płytki w poszukiwaniu wroga stojącego na jednym z nich. Jeśli chcesz zdobyć najbliższych wrogów, możesz posortować swój zestaw według odległości.

Może to być najskuteczniejsza metoda, szczególnie jeśli planujesz robić inne rzeczy z mapą wpływów, takie jak mgła wojny lub wyszukiwanie ścieżek.

Oto wideo, które nakręciłem, wyjaśniając tę ​​koncepcję: https://www.youtube.com/watch?v=MEd6XV2Pecw .

A oto implementacja: https://www.youtube.com/watch?v=y_ewoxlZlgc

Nie polecam inicjowania kolekcji jednostek kafelków siatki podczas uruchamiania - zamiast tego tylko wtedy, gdy kolekcja jest potrzebna.

Alternatywnie możesz użyć tablicy o długości X, jeśli wiesz, że na kafelku nigdy nie będzie więcej niż X jednostek.

JPtheK9
źródło