Фоновое дрожание с отключенным v-syn c в автономной сборке (высокая частота кадров / 300 + кадров в секунду) - PullRequest
0 голосов
/ 13 февраля 2020

Итак, последние 2 месяца я переделывал свой PlayerController, чтобы он был жестким телом, чтобы иметь больше взаимодействий с твердыми телами, то есть толкать объекты. Все прошло очень хорошо, пока я не начал тестировать свою игру в автономной сборке. Я сразу заметил странное дрожание / заикание на заднем плане (проигрыватель работает плавно), когда v-syn c выключен (с выключенным v-syn c мой компьютер запускает игру со скоростью 300fps +). Сначала я думал, что это как-то связано с Cinemachine, я использую CinemachineFreeLook, но, если честно, на данный момент я не уверен, что именно Cinemachine вызывает дрожание / заикание. Стоит отметить, что джиттер / заикание не является постоянным, в то время как fps кажется постоянным, джиттер / заикание может исчезнуть на go примерно на 20 секунд и вернуться после. Очевидно, что на прошлой неделе я провел множество исследований и читал множество постов о FixedUpdate и Update, но, к сожалению, безуспешно.

Я пытался добавить в этот пост как можно больше информации чтобы лучше понять мой проект, но сначала то, что я уже пробовал;

  • Изменение фиксированного временного шага с 0,02 до 0,01. (Этот вид работает, но я бы хотел предотвратить изменение Фиксированного временного шага)
  • Включение интерполяции / экстраполяции. (Теперь есть джиттер с включенным и выключенным v-syn c)
  • Изменение метода обновления CinemachineBrain на FixedUpdate / LateUpdate вместо SmartUpdate.
  • Деконструкция сцены и удаление некоторых тяжелых о таких вещах, как Volumetri c Lighting и Planar Reflections.
  • Создание действительно скелетного PlayerController только с кодом для перемещения плеера.
  • Удаление папки библиотеки моего проекта. (Прочтите это где-нибудь онлайн, но не повезло)
  • Включение моего контроллера Xbox One, чтобы убедиться, что используется только один вход.
  • Переключил здание из оконного полноэкранного режима в эксклюзивный полноэкранный.
  • Выключил один монитор во время тестирования.
  • Переместить весь мой код в FixedUpdate.
  • Добавил эти 3 скрипта и изменил порядок выполнения скриптов
    (Не удалось заставить это работать)
  • Поместите входную логику c в FixedUpdate.

Ниже вы можете увидеть оба моих сценария движения, один из которых является частью моего реального PlayerController, в то время как другой был тот, который я написал для barebone-плеера.

void FixedUpdate() {

    _isGrounded = Physics.CheckSphere(_groundChecker.position, GroundDistance, Ground, QueryTriggerInteraction.Ignore);

    _inputs = Vector3.zero;
    _inputs.x = Input.GetAxis("Horizontal");
    _inputs.z = Input.GetAxis("Vertical");
    _inputs.Normalize();

    if (_inputs != Vector3.zero)
        transform.forward = _inputs;
        _body.MovePosition(_body.position + _inputs * Speed * Time.fixedDeltaTime);
}

Это сценарий, который я написал для контроллера barebones-плеера.

void FixedUpdate() {
    if (pushControllerScr._pushBlocker) {
        input = Vector3.zero;
    } else {
        input = new Vector3(InputManager.MainHorizontal(), 0, InputManager.MainVertical());
    }
    RunAxis();
    inputDir = input.normalized;
    inputDir.Normalize();

    // Makes the player able to move, while not landing or being dead
    if (!landState && !climbManagerScr.isClimbing) {
        Move(inputDir, running);
    }
}

void Move(Vector3 inputDir, bool running) {
    if (inputDir != Vector3.zero) {
        float targetRotation = Mathf.Atan2(inputDir.x, inputDir.z) * Mathf.Rad2Deg + cameraT.eulerAngles.y;

        transform.eulerAngles = Vector3.up * Mathf.SmoothDampAngle(transform.eulerAngles.y, targetRotation, ref turnSmoothVelocity, GetModifiedSmoothTime(turnSmoothTime));
    }

    float targetSpeed = ((running) ? runSpeed : movementSpeed) * inputDir.magnitude;
    stateInfoBaseLayer = _anim.GetCurrentAnimatorStateInfo(0);

    if (stateInfoBaseLayer.IsTag("Climbing") || stateInfoBaseLayer.IsTag("Standing")) {
        currentSpeed = 0f;
    } else {
        currentSpeed = Mathf.SmoothDamp(currentSpeed, targetSpeed, ref speedSmoothVelocity, GetModifiedSmoothTime(speedSmoothTime));
    }

    if (stateInfoBaseLayer.IsTag("AirIdle") && currentSpeed > walkSpeed) {
        currentSpeed = walkSpeed;
    }

    velocity = transform.forward * currentSpeed + Vector3.up * _rb.velocity.y;

    if (_capsuleCol.enabled) {
        _rb.MovePosition(_rb.position + velocity * Time.deltaTime);
    }
}

Именно это я и использую в своем скрипте PlayerController

Ниже вы можете увидеть некоторые кадры дрожания / заикания. Было довольно сложно его запечатлеть, поскольку использование любого программного обеспечения для записи, такого как OBS, сбрасывало частоту кадров в моей игре до такой степени, что джиттер / заикание исчезали. Извините за запись по телефону, но это был, честно говоря, единственный способ.

Кадры моей игры, демонстрирующие дрожание / заикание, особенно заметное вокруг желтого корабля.

И наконец вот альбом с некоторыми соответствующими настройками в инспекторе. Imgur Album

1 Ответ

0 голосов
/ 13 февраля 2020

Глядя на вашу запись, выглядит, как будто плеер гладкий и все остальное.

По моему опыту 99% времени означает, что дрожание исходит от камеры, которая не синхронизируется правильно с плеером.

Кажется, вы сделали правильные вещи, и обычно объединение должно работать нормально:

  1. CinemachineBrain должно обновиться на FixedUpdate
  2. Используйте интерполяцию / exrapolate для Rigidbody вашего игрока (мы выбрали экстраполирование)
  3. Применяйте силы / изменения к физическим объектам исключительно в FixedUpdate

Если вы делаете все 3 вместе , это должно работать безотказно независимо от vsyn c, частоты кадров, фиксированного времени дельты и т. д. c

Очевидно, что в вашем конкретном проекте c может быть что-то еще, что испортит его ; но я видел эту проблему бесчисленное количество раз, и обычно эти совместные шаги должны решить ее.

...