Как стать автором
Обновить

Комментарии 56

После первого ответа можно обновить страницу — так не нужно будет отвечать на каждую анимацию ^___^
Это значит, что если луч попал в объект, от пули уклониться невозможно,
Заголовок спойлера

Но вроде как пофиксили уже.
Интересное как такое вообще попало в продакшен))
Да чемодан с такими возможностями можно выдавать в кино следующему Джеймсу Бонду!
Не совсем так: его сначала пофиксили как баг, а потом вернули с обновлением, уже как фичу
Оно там и было, исходя из механики игры после прицеливания предмет должен был попадать без промаха.
Просто чемодан очень медленно передвигался, на других предметах не так заметно.
Заголовок спойлера

Вспоминаются тепло любимые PPC из MechWarrior 2, которыми можно было нанести повреждения почти на любом расстоянии (даже вне зоны действия радара), главное — попасть на таком расстоянии.
А мне Battlefield 3, я там ракетами попадал через всю карту, по косвенным признакам.
В баттле офигенная механика командного взаимодействия, когда товарищи на земле подсвечивают противника и противник огребает от авиации или танков на дальнем расстоянии. Очень здорово, когда люди этим реально пользуются.
Очень здорово, когда люди этим реально пользуются.

Судя по тому количеству банов, что я получал, не все в восторге)

Кстати не всегда подсветка нужна, открыл для себя я такую возможность увидев на границе прорисовке облако от разгоняющихся винтов вертолета)
В тройке тоже самое. Бесконечно летит.
Хорошо и понятно написано, но хотелось бы больше технических деталей на примере каких либо движков или игр. Интересно, как гибридные системы будут рассчитываться при разных задержках, к примеру при 30ms и при 200ms.

П.С. была интересная статья на хабре, но в году так 2013 или 2016. Там очень подробно это всё описали, но по моему на примере hitscan. Явно что-то да уже поменялось.
Для физики принято делать фиксированный FPS.
А сетевая задержка особой роли не играет.
С 2013 года врядли что-то особо поменялось. Стрельба не та тема, где кто-то что-то хочет менять, ибо она уже давно отлично работает.
Постреляйте в тот же CS:GO при пинге 200+ms — после скажите, что сетевая задержка не играет особой роли в шутерах.
А если ещё и игроков под 100 будет… на примере любого survival (SCUM, DayZ, Tarkov) — сколько боли будет в глазах при пинге в 200 ms :)

По поводу фиксированного FPS и так понятно, но ведь каждый просчёт «1 кадра» должен учитывать и задержку каждого игрока, иначе картинка будет далеко не синхронная: стреляешь в бегущего игрока, а убить не можешь (если конечно не просто hitscan, но и тут нужно учитывать задержку). А вот как такое работает при гибридной реализации, было бы интересно прочитать.
Задержка играет роль для игрока. С херовым пингом будешь проигрывать всё время.
Но с точки зрения реализации алгоритмов стрельбы она никакой роли не играет.
Стрельба ведется любым методом, просто ведется она не по текущему состоянию актора, а по предсказанной модели.
Могу не согласиться)) Доводилось играть в CS 1.6 с пингом 120+, так вот в меня никто попасть не мог, зато я попадал нормально)) возможно, это особенность движка CS 1.6, или я так приспособился тогда, но вот как-то так)
С херовым пингом будешь проигрывать всё время.

Вы мало играли с людьми умеющими пользоваться преимуществами херового пинга. У них есть огромное преимущество в раше (rush) и префайре (prefire), так как при активном движении, они могут замечать врага раньше чем он заметит их.
В CS:GO эталонно отвратительный сетевой код из-за возможности полного рассинхрона клиента и сервера даже при нахождении обоих на одной машине, плохой пример.
Есть какие нибудь подробности почитать на эту тему?
Да достаточно поднять сервер c картой Fast Aim/Reflex Training Map (там боты бегут на игрока) с любым тикрейтом (хоть 256) у себя и включить sv_cheats 1; sv_showimpacts 1.
В принципе в игре можно сорвать синхронизацию поворота камеры на 90° при любом тикрейте.
в Wolfenstein 3D даже не совсем hitscan.
вернее там объекты все кубиками
Скорее квадратиками, ибо до кубиков движок не дорос, а спрайты там плоские.
ну да. квадратики, конечно :)
Все объекты кубиками (хитбоксами) — это не исключает hitscan. Просто проще рассчитать попадание луча на кубик. С этим бывают интересные баги. В Half-Life 2, пример, хитбоксы были такого размера, что для убийства противника было достаточно выстрелить из арбалета в область в районе головы. Стрела попадает левее на 10 см — противник умирает от хедшота.

Возможно нубский вопрос — а как реализовать такое затенение на растоянии как на первой гифке? В оригинале-то понятно, что текстурку подкрашивали в зависимости от расстояния, а в том же Unity как такое сделать задешево? Кроме "черного тумана" только затенение шейдером в голову приходит.

Постэффектом по глубине.

разве это потребует меньше ресурсов чем затенение шейдера в зависимости от расстояния до игрока/источника света? К тому же, как в таком случае реализовать подсветку фонариком…

Если сцена строиться в 3d а не рейтрейсингом, то проще буфером глубины поскольку он уже есть. Если рейтрейсингом — когда мы кастуем лучи до окружения, мы можем измерить дистанцию от источника света (камеры) и затенить шейдером.

Спасибо, добрый человек, пойду курить буфер глубины и как выборочно отключать постпроцессинг в зонах подсвеченных фонариком (pp volume? / mask)

LODами?
Вспомнились игрушки MDK/MDK2, там была снайперская пуля, к которой цеплялась камера.
Меня больше интересует, как hitscan компенсируется в мультиплеере, где у обоих игроков скачущие пинги и в реальности, если ты нажимаешь выстрел, он происходит через миллисекунд 100 позже (твой лаг обработки выстрела + лаг движений того парня от него до сервера и до тебя). Нельзя ведь, чтобы игроки никогда не попадали?
На данную тему можно почитать статьи от marsermd. Если вкратце — сервер откатывается на тот такт, в который клиент произвел выстрел (для этого нужен физический движок, который умеет хранить историю), и выполняет raycast в прошлом.
Вот про эти стать я и упоминал в комментарии выше, спасибо добавил в избранное.
Но судя по статье как раз речь идёт о hitscan, а после уже с raycast в прошлом — работает ли такая схема с гибридом? когда и hitcast и одновременно создаётся объект как пуля.

А почему нет?

С проджектайлами история сложнее, конечно. И в моей статье это никак не описано.


Решений есть несколько:
1) не делать клиентского предсказания для проджектайлов. Самый простой способ и довольно популярный года до 2010, когда проджектайлы обычно были гранатами — редко используемыми и непредсказуемыми объектами
2) не делать клиентского предсказания для проджектайлов, но делать компенсацию лагов на задержку выстрела. Используется на некоторых оружиях в овервотче. Идея в том, что у нас есть задержка от команды до самого выстрела. Например, это время на анимацию натяжения лука. В таком случае мы из этой задержки вычитаем пинг.
3) делать клиентское предсказание с лагокомпенсацией. Это самая жесть.
а) на клиенте мы выпускаем пулю сразу и симулируем её передвижение с клиентским предсказанием
б) на сервере мы делаем компенсацию лага, т.е. делаем вид что пуля уже была запущена Ping секунд назад. Т.е. эффективно нам нужно подвинуть пулю вперед на расстояние (Ping * Velocity)
в) на вражеском клиенте мы эту пулю должны привести в то же время, что и нашего персонажа (TServer + Ping), чтобы было легче уворачиваться. Для этого нам опять же надо воспользоваться клиентским предсказанием.


И тут проблема: с точки зрения вражеского клиента, пуля заспавнится на расстоянии 2 Ping Velocity От стрелка. Это решается исключительно визуальным сглаживанием — экспоненциально интерполируем позицию пули для рендеринга между позицией выстрела и предсказанной позицией пули.


Этот способ также используется в овервотче (могу ошибаться насчёт экспоненциальной интерполяции снаряда)

Т.е. по пункту 3 если вдруг пуля уже выпущена, а враг двигаясь по намеченной траектории вдруг за какие то доли секунды нажимает шаг влево/вправо и т.д. (начинает «мансить» — по моему так оно называется), всё равно получит пулю «в лоб» как ни крути? Т.к. предсказать клиент не может куда шагнёт игрок (предсказания ведь явно рассчитываются по вектору в сторону движения)?
(Ping+Velocity)+(TServer+Ping) может, да и будет явно больше чем приемлемая компенсация погрешности (общая маленькая задержка, к примеру пинг меньше 10 ms), чтобы при большом кол-ве клиентов делать такие предсказания.
Т.е. по пункту 3 если вдруг пуля уже выпущена, а враг двигаясь по намеченной траектории вдруг за какие то доли секунды нажимает шаг влево/вправо и т.д. (начинает «мансить» — по моему так оно называется), всё равно получит пулю «в лоб» как ни крути?

Из опыта игры в Overwatch на далеких серверах — судя по всему да. При пинге 30-40 на европейских такого не замечал, а вот при игре на американских серверах при задержке 130-140 схлопатать хэдшот от MсCree или стрелу от Hanzo в момент этой доли секунды, когда нажимаешь влево\вправо — такое бывает. Причем на реплее от лица игрока этого движения нет, а ты успеваешь нажать кнопку и поидее должен был бы уже немного сдвинуться (и даже кажется что сдвинулся, но я это склонен списывать на предсказания собственного мозга).
Другое дело что на американских серверах все равно, к сожалению, приятнее играть из-за контингента и подхода к процессу, но это уже к вопросам предсказания попаданий слабо относится.
Информация о том, что вы нажали влево/вправо просто не успевает дойти до сервера из-за пинга, то есть для сервера вы в этот момент стояли на месте. Если у стреляющего высокий пинг, то на сервере моделируется ситуация на время (ваш пинг + пинг стреляющего). Ладно если речь идёт про шаг в сторону, иногда убивают «из-за угла». Если не знать, как работает сетевой код, можно подумать, что стреляющий — читер. Увы, в нашем неидеальном мире с ограниченной скоростью света приходится идти на компромиссы для получения всеми игроками одинаково увлекательного игрового опыта.

Не совсем в тему: В юности я плотно залипал в одну сетевую игру, где была снайперская винтовка с принципом поражения hitscan. Один из постоянных игроков играл с очень плохим интернетом — пинг иногда доходил до секунды. Этот игрок играл за снайпера. Добраться до снайперской позиции ему стоило немалых усилий (движение происходило рывками), но когда он добирался, вычислить его позицию было довольно сложно. С моей стороны это выглядело так: я забегаю в здание и умираю от снайперского выстрела. Делаю вывод, что убили меня через окно или дверь, и ищу снайпера в местах, откуда окна и двери простреливаются, но этот вывод не верный. Снайпер с секундным пингом пустил в меня пулю «в своём мире», который находится в прошлом на секунду, и в «его мире» я умер на улице, а не в здании.

Ещё на статьи Pixonic стоит обратить внимание.

Есть отличное видео на Battle(Non)Sense с наглядными поясненинями как это решается в современных шутерах www.youtube.com/watch?v=hiHP0N-jMx8

На этом канале постоянно разбирается неткод, пинги современных игр и всякое такое, рекомендую, если вопрос интересен.
Если мы добавляем в сцену быстролетящую пулю, то как бороться с тем, что она может не замечать столкновения с препятствиями?
Ну, например, делать рейкаст от положения пули в предыдущем кадре по вектору её движения и ретроспективно предсказать коллизию.
В современном физическом движке это учтено.
Собственно это не только пуль касается, но, например, телепортацию самого игрока сквозь тонкие стены. Когда теже спидранеры набирают скорость, замедляют ФПС у игры и пролетают сквозь стену, потому что в предыдущем кадре актор был перед стеной, а в последующем за ней.
Но в современных физдвижках такое уже не прокатывает.
Попадания пуль вычисляются на этапе проверки коллизий. Коллизии (в общем случае) проверяются каждый такт вычислений физического движка (не путать с FPS).
Вычисления коллизий начинаются с определения вектора скорости объекта, он откладывается от текущего положения к будущему.
Затем по концу вектора определяется положение Bounding Box-ов (BBox, ограничивающий параллелепипед) пули и движущихся окружающих объектов. По пересечению ББоксов определяются все столкновения и попадания.
Для упрощенных вычислений ББокс пули может отсутствовать и тогда вычисляется только пересечение вектора движения пули и ББоксов окружающих объектов.
В частном случае (например, в старых играх) ББокс статичный и если нет дополнительных проверок, то объекты могут пролететь один сквозь другого, чем пользуются читеры и абьюзеры.
В современных движках могут применяться разные алгоритмы определения коллизий. Чаще всего — комбинированные, для каждого типа объектов свой алгоритм. Могут определяться точки касания пересекшихся объектов для точного расчета физики. Могут применяться вытягивающиеся ББоксы, у которых чем выше скорость, тем более вытянутыми они станут.
Можете почитать про алгоритмы CCD (Continuous Collision Detection).
Везде проблема с туннелированием решается по разному.
Ну и проблема эта возникает не только с линейным движением, но и с вращательным.
Havok, например, не решает в CCD проблему быстрого вращения.
одно из решений — вытягивать хитбокс пули, в зависимости от скорости
То есть колайдить не пулю и стенку, а объём пространства, занимаемый пулей за время между кадрами физики.

 PS: надо читать коменты, перед тем как их писать. Выше уже написали про CCD
Интерполируем промежутки с помощью hitscan
Помнится, в старом добром DOOM при пилении розового бодуна бензопилой на нем появлялись кровавые всплески, как от шотгановской картечи)))
Помню как был 90х поражен игрой Delta Force где у пуль была скорость, баллистика. Надо было брать упреждение при стрельбе из снайперской винтовки. Зато попасть в бегущего врага с километровой дальности вызывало непередаваемые эмоции.
Статья как работают пули и нету про Unreal Tournament 1999?
Да как же это?.. :(

— Хитскан от снайперки и луча шок ружья. Энфорсеры. Короткий хитскан плазмой в режиме луча.
— Бешеный молоток и пила — тоже суперкороткие рейкастеры — «пули» ближнего боя! (Здесь кстати можно было бы немного осветить тему «пуль» которые мечи, молотки и прочее добро классического РПГшника)

Баллистика летящего предмета, целый ворох на любой вкус:
— по прямой — плазма в режиме сгустков, шары с шок ружья, минигановские патроны, ракеты, резаки.
— по гравитации — ракетница в режиме гранат, флака (особенно картинно ядром), слизь из великой кляк-пушки которое биоружьё. Что касается гравитации, обычно траекторией получается парабола, но карты с переменной зональной гравитацией (Хотя бы DM-Morpheus и CTF-Face) этот стереотип ломают ))
— по Архимеду — зелёная слизь биоружья при стрельбе под водой… быстро тормозится и всплывает!
— чёртовы отскоки резаков от стен в коридорах, многократные, лютая вещь. Ну и отскоки гранат конечно.
— остановки, но всё ещё активность «пуль» — прилипшие на время зелёные биокляки, работающие фактически как мины, ну и классические доскакавшие гранаты, но которым ещё не пришло время детонировать.

А также особые вариации про «летящий предмет», которые не укладываются в «баллистику»:
— генерация пулей при хите новых пуль! Как правило других. Это большая биокляка биоружья в альтернативном режиме, которая при хите с поверхностью рождает россыпь обычных кляк. Это флак-ядро, при ударе о стену рождающее россыпь разлетающихся флак-осколков.
— управляемая пуля! Точнее не пуля, а ракета. Ядерная, с камерой на ракете, рули в любом направлении сколько хочешь.
— попадание пулей в пулю. Ядрён ракету можно пристрелить, и она бахнет где пристрелили в уменьшенном по последствиям формате.
— микс и генерации и попадания пуля-пуля. Эпическое шок ружьё у которого есть три вида пуль — луч обычной стрельбы, шок-шар альтернативной стрельбы и мощная рвущая шок-сфера, которая создаётся если попасть выстрелом в форме быстрого луча по шок шарику. И не обязательно своему.

Волновой фронт. Отдельный класс «пуль» обойдённый вниманием!
Ядрён ракета при штатном подрыве (хит в стенки, чувака или команда подрыва в полёте в режиме управления) создаёт «пулю-волну» — объект расширяющегося до некоторого (большого) радиуса волнового фронта ядерного удара, который по принципу эмм… медленного рейкаста рвёт всех, кто не попрятался за стенки.

Ну и на закуску.
Конечно заслуга QuakeIII Arena про особый прошивающий рейкаст рельсы отмечена по праву.
Про прошивающий рейкаст тогда уж старый добрый прострел стен с уменьшением урона в Counter Strike 1.5 более чем правильно вспомнить тоже.

Ну и ещё до сих пор помню то восхищение игрой Turok, самой первой, атмосфернейшей 3D-стрелялки про динозавров, где кроме прочего был лук и стрелы, которые летали по баллистике и втыкались, и их можно было собрать обратно из стен, земли, а также головы и прочих частей грохнутых рептилий. Жалко всё таки иногда терялись стрелы-то, а так эффектнейший почти бесконечнопатронный пушка. Особенно когда наловчишься на пределе видимости тумана войны навешивать хедшоты.

PS: Да, а про попадания пуль в пули кстати хорошо расскажут танчики из пахнущего ионами электроники картриджа для денди.

Не хватило мне статьи, не хватило.

Отличный коммент!

В Звёздных Войнах энерголучи оружия летят довольно медленно, и в старых Battlefront часто можно видеть через снайперский прицел, как цель умирает до того, как до него долетает энерголуч.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории