Подсистема динамической дальности прорисовки и дальности тумана в зависимости от FPS. Помогает адаптировать отрисовку вашей карты под производительность целевого ПК игрока в реальном времени.
Этот кусок кода взят из карты XGM New Year 2010.
В теории должен работать и в Reforged, но не тестировали.
В теории должен работать и в Reforged, но не тестировали.
Принцип работы
Игра каждые 0.5 сек триггерит выделение дамми-юнита на карте и сверяет, как часто этот юнит реально выделяется.
При нагрузке на ПК и понижении количества кадров в секунду частота выделения юнита падает и приходит время уменьшать дальность прорисовки. И наоборот.
При нагрузке на ПК и понижении количества кадров в секунду частота выделения юнита падает и приходит время уменьшать дальность прорисовки. И наоборот.
Также система меняет дальность тумана на значения:
- минимум: дальность прорисовки - 1600
- максимум: дальность прорисовки
Исходный код
На данный момент код рассчитан на 1 игрока. Отлично подходит для разных ингейм синематиков и кампаний с видом от третьего лица.
Глобальные переменные в случае jass, а не vjass, можно объявить вручную и проставить везде udg_ префикс.
Код
globals
real CameraSystem__CAM_MAX_DIST_dynamic=10000.0
boolean FPScorrector___enabled=true
timer FPScorrector___checker1=CreateTimer()
timer FPScorrector___checker2=CreateTimer()
boolean FPScorrector___selected=false
trigger FPScorrector___upd=CreateTrigger()
trigger FPScorrector___reg=CreateTrigger()
unit FPScorrector___unit = null // задать нужного даммика для кликов
endglobals
function FPS_norm takes nothing returns nothing
if(CameraSystem__CAM_MAX_DIST_dynamic==10000.0)then
return
elseif(CameraSystem__CAM_MAX_DIST_dynamic<10000.0)then
set CameraSystem__CAM_MAX_DIST_dynamic=CameraSystem__CAM_MAX_DIST_dynamic+500
else
set CameraSystem__CAM_MAX_DIST_dynamic=10000.0
endif
endfunction
function FPS_speedup takes nothing returns nothing
if(CameraSystem__CAM_MAX_DIST_dynamic>(1600.0*2.0))then
set CameraSystem__CAM_MAX_DIST_dynamic=CameraSystem__CAM_MAX_DIST_dynamic-500
else
set CameraSystem__CAM_MAX_DIST_dynamic=(1600.0*2.0)
endif
endfunction
function FPScorrector___select takes nothing returns nothing
set FPScorrector___selected=true
endfunction
function FPScorrector___check2 takes nothing returns nothing
if(FPScorrector___selected)then
call FPS_norm()
endif
endfunction
function FPScorrector___check1 takes nothing returns nothing
if (FPScorrector___selected) then
set FPScorrector___selected=false
call ClearSelection()
call TimerStart(FPScorrector___checker2,0.16,false,function FPScorrector___check2)
call SelectUnit(FPScorrector___unit,true)
else
call FPS_speedup()
endif
endfunction
function Trig_FPS_corrector takes nothing returns nothing
if (FPScorrector___enabled) then
call ClearSelection()
set FPScorrector___selected=false
call TimerStart(FPScorrector___checker1,0.3,false,function FPScorrector___check1)
call SelectUnit(FPScorrector___unit,true)
endif
endfunction
function FPS_corrector_init takes nothing returns nothing
call TriggerRegisterTimerEvent(FPScorrector___upd,0.5,true)
call TriggerRegisterPlayerUnitEvent(FPScorrector___reg,Player(0),EVENT_PLAYER_UNIT_SELECTED,null)
call TriggerAddAction(FPScorrector___upd,function Trig_FPS_corrector)
call TriggerAddAction(FPScorrector___reg,function FPScorrector___select)
endfunction
Использование
В инициализации задать переменную FPScorrector___unit в какого-то скрытого юнита этого же игрока на карте, который будет служить кликером.
В главном цикле движения вашего юнита или просто создать таймер с периодом типа 0.1 и вызывать данные функции:
call SetCameraField(CAMERA_FIELD_FARZ,CameraSystem__CAM_MAX_DIST_dynamic,0.0)
call SetTerrainFogZ(CameraSystem__CAM_MAX_DIST_dynamic-1600.0,CameraSystem__CAM_MAX_DIST_dynamic)
Используйте переменную FPScorrector___enabled чтобы включать в синематиках или в начале игры и выключать систему в реальном геймплее.
Например, можно начать игру с синематика, чтобы подстроить FPS, а затем выключить систему и начать геймплей.
Например, можно начать игру с синематика, чтобы подстроить FPS, а затем выключить систему и начать геймплей.
Мультиплеер
Для мультиплеера нужно выполнять все вышеперечисленные функции для каждого из игроков и переменные должны быть массивом.
А вызов SetCameraField и SetTerrainFogZ должны выполниться циклом для каждого игрока внутри GetLocalPlayer() == player
А вызов SetCameraField и SetTerrainFogZ должны выполниться циклом для каждого игрока внутри GetLocalPlayer() == player
UjAPI
В UjAPI есть специальная локальная функция GetFPS - можно заменить кликер дамми на вызов этой фукции: github.com/UnryzeC/UjAPI/blob/main/uJAPIFiles/common.j#L4664
P.S.
Подсистема является черновиком и не гарантирует свою работу прямо из коробки. Возможно, где-то надо подшаманить.