Time

Игровые часы: как быстро идёт игра и сколько стоит кадр. Time.scale замедляет или ускоряет всю игру, Time.paused её замораживает — и оба достигают собственных симуляций движка (физика, аниматоры, частицы), так что поставленный на паузу аспект и поставленное на паузу твёрдое тело согласны между собой.

Обзор

TypeScript
class PauseMenu extends System<'pauseMenu'> {
  updateWhilePaused = true                    // продолжает тикать, пока мир заморожен
  fade = 0
  private onKey = (e: InputKeyEvent) => { if (e.code === 'Escape' && !e.repeat) Time.paused = !Time.paused }
  onAttach() { Input.on('keydown', this.onKey) }
  onDetach() { Input.off('keydown', this.onKey) }
  update() {                                  // на паузе dt равен 0: используем настенные часы
    this.fade = Time.paused ? Math.min(1, this.fade + Time.unscaledDt * 4) : 0
  }
}

const scene = new Scene().system(PauseMenu)
scene.open()
Time.scale = 0.25                             // замедленная съёмка для kill cam

API

TypeScript
Time.scale: number         // 1 нормально · 0.5 половина скорости · 2 двойная (≤ 0 / NaN / Infinity → 0, заморожено)
Time.paused: boolean       // заморозить игру; `scale` запоминается и восстанавливается при возобновлении
Time.effectiveScale        // множитель, с которым движки работают прямо сейчас (0 на паузе)
Time.dt: number            // дельта этого кадра в ИГРОВЫХ секундах — то, что получает update(dt); 0 на паузе
Time.unscaledDt: number    // дельта этого кадра по настенным часам, секунды (движки ограничивают её до 0.05)
Time.fixedDt: number       // 1/60 — то, что всегда получает updateFixed(dt) (только чтение)
Time.now: number           // игровые секунды с запуска часов (масштабированные; останавливаются на паузе)
Time.unscaledNow: number   // секунды по настенным часам с запуска часов
Time.frame: number         // кадров отправлено с запуска часов (кадры на паузе считаются)
  • update(dt) / updateBefore(dt) получают Time.dt. На паузе каждый обновляющий пропускается, кроме тех, у кого updateWhilePaused = true — они вызываются с dt = 0 и сами читают Time.unscaledDt — то же разделение, что deltaTime / unscaledDeltaTime в Unity.
  • updateFixed(dt) всегда получает Time.fixedDt; scale меняет, сколько фиксированных шагов вмещает кадр, но никогда не их длину. На паузе их нет — даже для updateWhilePaused.
  • Часы приводит в движение диспетчер аспектов, который запускается с первым аспектом или системой, определяющей метод update: до этого dt, now и frame остаются 0.
  • Масштаб передаётся каждому движку через его бридж setTimeScale (с проверкой наличия): шаги физики, часы аниматоров и системы частиц продвигаются на dt × scale. Хост, чей движок старше этого хука, держит свои симуляции на скорости настенных часов, пока игровой код всё равно масштабируется — там останавливай тела сам.
  • Твины на часах 'game' (animate) берут масштаб 3D-движка: они замедляются и встают на паузу вместе с Time только когда существует 3D Scene — в чисто 2D-приложении они идут на скорости настенных часов.
  • setTimeout / setInterval — таймеры хоста на настенных часах — они не масштабируются и не ставятся на паузу.

Смотрите также

  • Аспекты — updateWhilePaused, фазы, потребляющие dt
  • Input — Input.on('keydown') для одноразовых клавиш вроде переключателя паузы
  • Глобалы хоста — setLoop, setTimeout