Итак, последние 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