Прибор ночного видения на UnrealScript: классический туториал и перенос в Killing Floor
Вики OldUnreal хранит классический туториал по прибору ночного видения (NVG) для Unreal Tournament 1999 года. Killing Floor работает на куда более позднем движке, так что код как есть не скомпилируется, но сама схема показывает, как строить любой клиентский визуальный эффект: что видит игрок, что видят остальные и во что обходится каждая часть по производительности. Ниже разбор оригинала и список того, что менять для KF.
Дождь, туман и мутант в паре метров: как раз для таких сцен и нужно ночное видение.
Схема
Прибор делает две вещи:
- Осветляет и тонирует обзор самого игрока, сдвигая «свечение» экрана (общий сдвиг цвета и яркости).
- Делает других персонажей заметнее, надевая на них полупрозрачную, слегка раздутую копию их же меша, так что вокруг них появляется светлая аура.
Сверху добавляется «эффектная» часть: анимированная шумовая текстура 256×256 на весь экран. Всё это работает на клиенте: ни ваш оверлей, ни ауры никто другой не видит.
В коде три класса:
| Класс | Роль |
|---|---|
NVGMutator | HUD-мутатор: цепляется за PostRender() HUD и рисует оверлей, если у владельца включён прибор |
NVG | Предмет инвентаря: команда переключения, изменение свечения, создание аур |
NVGIllum | Эффект ауры: повторяет меш и анимацию владельца, рисуется полупрозрачным и без освещения |
NVGMutator: рисуем поверх экрана
HUD-мутаторы в UT99 встают в цепочку на HUD игрока и каждый кадр получают вызов PostRender(Canvas). Мутатор ищет прибор в инвентаре игрока, но только раз в 0.3 секунды для экономии, и рисует оверлей во весь экран:
// Draw overlay if NVG activated
if ( aNVG != None && aNVG.bEnabled )
{
C.SetPos(0, 0);
C.Style = ERenderStyle.STY_Translucent;
C.DrawIcon(Texture'Static_a00', FMax(C.ClipX, C.ClipY)/256.0); // assumes a 256x256 texture
}
if ( NextHUDMutator != None )
NextHUDMutator.PostRender( C );
PostRender всегда передаётся следующему HUD-мутатору. Если разорвать цепочку, сломаются все остальные HUD-моды на сервере.
NVG: переключение и свечение экрана
replication
{
reliable if (bNetOwner && ROLE == ROLE_Authority)
bEnabled;
reliable if (Role < ROLE_Authority)
NVGToggle;
}
exec function NVGToggle()
{
bEnabled = !bEnabled;
Owner.PlaySound(Sound'UnrealShare.Pickups.FSHLITE1',, 1.5 * Pawn(Owner).SoundDampening);
AdjustGlow();
}
simulated function AdjustGlow()
{
local PlayerPawn PP;
PP = PlayerPawn(Owner);
if (PP == None)
return;
if (bEnabled)
PP.ClientAdjustGlow(-0.15, vect(139.0, 218.0, 72.0)); // brighten and tint green
else
PP.ClientAdjustGlow(+0.15, vect(-139.0, -218.0, -72.0)); // undo exactly
}
Тут важны две детали:
- Изменение свечения относительное, поэтому выключение должно точно отменять то, что сделало включение. Предмет вызывает
AdjustGlow()ещё и изDestroyed()иDropFrom(), иначе игрок, который умер или выбросил прибор, останется с зелёным экраном. NVGToggleреплицируется на сервер, аbEnabledвозвращается только владельцу (bNetOwner).
NVGIllum: аура
Раз в несколько тиков прибор ищет персонажей в радиусе Range (900 единиц) через VisibleCollidingActors и выдаёт каждому NVGIllum из переиспользуемого пула. Эффект копирует меш владельца, следует за ним через PHYS_Trailer и bAnimByOwner и рисуется как STY_Translucent и bUnlit с Fatness чуть больше, чем у владельца. Текстура тёмно-серая: UT рисует полупрозрачность сложением цветов, поэтому тёмно-серый выглядит как мягкая светлая оболочка. bOwnerNoSee скрывает вашу собственную ауру от вас.
Предупреждение о производительности
Автор намерил потерю около 15 FPS и сам назвал причину: foreach AllActors и VisibleCollidingActors в Tick(), даже если они срабатывают раз в три тика. Оверлей и свечение почти ничего не стоят. Держите это в голове при любом переносе.
Перенос в Killing Floor
KF использует кодовую базу Unreal Engine 2.5, унаследованную от UT2004, поэтому строительные блоки называются иначе. Считайте таблицу картой для собственного исследования и сверяйте каждое имя с исходниками скриптов KF.
| Часть в UT99 | Аналог в Killing Floor / UE2 |
|---|---|
HUD-мутатор с PostRender(Canvas) | Клиентский Interaction с bVisible=true и PostRender(Canvas), либо HUD-оверлей, если HUD KF его поддерживает; в сборках с ServerPerks обычно уже есть свой класс HUD, к которому можно подключиться |
PlayerPawn | Разделён на PlayerController (обзор, ввод, HUD) и Pawn (тело) |
ClientAdjustGlow(scale, fog) | Вспышка/туман обзора в PlayerController (ClientFlash, постоянные glow scale и fog). Помните, что мобы в KF сами используют экранные эффекты, поэтому возвращайте предыдущие значения, а не значения по умолчанию |
Предмет инвентаря TournamentPickup | Подкласс KFWeapon или Inventory, либо проще: клавиша, которую обрабатывает interaction вашего мутатора |
exec function NVGToggle | Привязать клавишу к команде, которую обрабатывает ваш код, например set input N mutate nvg с обработкой на сервере |
Оболочка NVGIllum вокруг персонажей | Возможна, но дорога в KF, где одновременно живы 30-60 мобов. Оверлей и яркость дают большую часть эффекта |
Геймплейные заметки для KF:
- Баланс. Многие карты KF держатся на темноте, а Commando и так видит Сталкеров и здоровье мобов. Бесплатное ночное видение сильно меняет сложность. Подумайте о привязке к перку, ограничении по времени или «батарейке».
- Читаемость. Полноэкранный шум в игре про толпы утомляет. Лёгкая виньетка и тонировка работают лучше тяжёлых помех.
- Белый список. Клиентский визуальный мутатор всё равно должен пропустить сервер; см. мутаторы из белого списка.