Как мне реализовать «осведомленность» противника?

12

Я использую Unity3d для разработки гибридного прототипа игры RTS / TD. Каков наилучший подход для «осознания» между юнитами и их врагами? Разумно ли, когда каждый юнит проверяет расстояние до каждого врага и вступает в бой, если находится в радиусе действия?

Подход, к которому я сейчас обращаюсь, заключается в том, чтобы на каждом юните была сфера-триггер Если враг нажимает на курок, подразделение узнает о нем и начинает проверку расстояния. Сохраняет ли это некоторые ненужные проверки?

Какова лучшая практика здесь?

Фил
источник
Я должен добавить, что количество юнитов / врагов будет в масштабе Верховного главнокомандующего
Фил

Ответы:

10

Посмотрите на ограничивающие иерархии томов (BVH). Они чаще всего используются при обнаружении столкновений, чтобы уменьшить количество проверок, необходимых при расчете столкновений или при рендеринге для выполнения отбраковки усеченного объекта. Поскольку вы уже используете сферы, я бы предложил дерево сфер, хотя другие тома, такие как AABB, могут быть более эффективными. Я не уверен, какую поддержку имеет Unity для таких вещей, которые я никогда не использовал, но, вероятно, что-то для этого уже есть в обнаружении столкновений или рендеринге частей движка.

По сути, вы хотите сгруппировать врагов, которые находятся рядом друг с другом, в несколько родительских сфер. Когда юнит перемещается, вы проверяете его сферу триггера на родительскую сферу вместо проверки каждого врага. Если сфера триггера пересекается с родительской сферой, вы должны проверить каждого врага внутри. Если этого не произойдет, вы можете отказаться от всех врагов, которые находятся внутри него. Вы хотели бы установить несколько уровней сфер на основе максимального размера сферы или количества врагов для каждой сферы и выполнять проверку на основе сферы высшего уровня. Тогда нужно просто спуститься по дереву, чтобы проверить каждого врага, не выполняя проверку расстояния для каждого.

Шаги требуются для каждого кадра:

  1. Переместить врагов
  2. Перестройте / обновите BVH для новых позиций противника
  3. Перемещайте юниты и проверяйте по отношению к сфере деревьев

Это может уменьшить количество проверок, необходимых при большом количестве врагов, но затраты на обновление и хранение дерева могут не стоить того, когда их не так много. Я не знаком с Верховным главнокомандующим, чтобы знать, что вы ищете, поэтому я предполагаю «сотни». Вам нужно будет профилировать в разных ситуациях, чтобы выяснить, будут ли накладные расходы того стоить вам.

Джоэл Бейкер
источник
3
+1 этот подход будет самым простым, хотя он будет иметь некоторые ошибки. ОП может захотеть реализовать это, а затем реализовать что-то вроде октодерева. Кроме того, в большинстве RTS блоки реагируют с некоторой задержкой. Фактически, большинство ИИ в играх рассчитывается на 10-30 кадров в секунду, где игра может работать со скоростью 30-60 кадров в секунду (цифры, конечно, являются приблизительными).
Самаурса
Спасибо, это было именно то, что мне нужно, чтобы сделать еще один шаг вперед. Я посмотрю BVH и как это реализовать в Unity. Очень педагогический и познавательный пост! +1
Фил
О, и проверь Верховного главнокомандующего, если ты в RTS. Это действительно очень хорошая игра, как и все игры Криса Тейлора.
Фил
7

Нет необходимости внедрять BVH, поскольку движок Unity по сути уже делает это за вас.

Просто прикрепите большой триггер ограничивающей сферы для каждой единицы (представляющей его диапазон) и обрабатывать OnCollisionEnter()и OnCollisionExit()обратные вызовы , чтобы отслеживать, какие враги находятся в пределах диапазона каждой единицы.

Обратите внимание, что интересующий вас случай - когда другая единица сталкивается со сферой, а не когда сфера другой единицы сталкивается со сферой.

BlueRaja - Дэнни Пфлугхофт
источник
1
Я думаю, что за это нужно проголосовать как минимум чуть выше принятого ответа. Принятый ответ хорош для изучения, но этот ответ должен быть сверху, так как это наиболее практичный способ.
Varaquilex
Я полагаю, ты имеешь в виду OnTriggerEnter()и OnTriggerExit()правильно?
Jibb Smart
1

Другим решением, которое очень хорошо масштабируется и может использоваться для множества других вещей, является карта влияния. Создайте набор плиток сетки вокруг блока для сканирования в радиусе X. Сканируйте эти плитки на наличие врагов, стоящих на одном из них. Если вы хотите получить ближайших врагов, вы можете отсортировать ваш сет по расстоянию.

Это может быть наиболее эффективным методом, особенно если вы планируете делать другие вещи с картой влияния, такие как туман войны или поиск пути.

Вот видео, которое я сделал и объясняющее концепцию: https://www.youtube.com/watch?v=MEd6XV2Pecw .

И вот реализация: https://www.youtube.com/watch?v=y_ewoxlZlgc

Я рекомендую не инициализировать коллекцию блоков мозаики при запуске, а только тогда, когда коллекция необходима.

Кроме того, вы можете использовать массив длины X, если вы знаете, что на плитке никогда не будет больше единиц X.

JPtheK9
источник