Интересно, кто такой Unity QA, который дал вам этот ответ, он заслуживает доверия.
Позвольте мне объяснить, что происходит, на самом деле .
1) Давайте начнем с fixedDeltaTime
: , это значение НИКОГДА не зависит от частоты кадров . Его можно установить в редакторе (в Edit->Project Settings->Time
), и это значение сохраняется во время выполнения, , если какой-либо сценарий не изменит его с помощью присвоения. Движок Unity сам по себе не меняет его.
2) Цикл физики: в полном цикле движка Unity выполнит несколько циклов физики (0,1 или более), а затем один цикл рендеринга. Количество физических циклов, выполненных на цикл рендеринга, основано на том fixedDeltaTime
и сколько времени прошло с момента последнего (т. Е. * deltaTime
цикла рендеринга).
Например, скажем, fixedDeltaTime = 0.0166667
, а время, прошедшее с последнего цикла по физике, меньше, чем, скажем, 10
мс. Unity не будет выполнять цикл Physics. Теперь предположим, что даже следующий кадр был обработан за 10
мс - это означает, что с момента последнего цикла по физике прошло 20
мс. Поскольку это больше, чем fixedDeltaTime
, Unity выполнит цикл по физике.
Иногда может случиться, что кадр отображается очень медленно (по непредвиденным причинам), например, за 40
мс. Чтобы поддерживать симуляцию физики согласованной, Unity должна запустить два цикла физики подряд, потому что 0.04/0.0166667 = 2.4
.
Имейте в виду, что Unity отслеживает разницу между временем начала последнего цикла Physics и следующим: если рендеринг длится 10
мс каждый кадр, а fixedDeltaTime
установлен на 166667
мс (60 Гц) , как только вы запустите среду выполнения, Unity выполнит первый цикл по физике, затем пропустит один после 1-го кадра рендеринга (поскольку вместо 166667
прошло только 10
мс), затем выполнит один цикл по физике после 2-го рендеринга кадр (20
мс передано против 166667
). Но теперь у нас есть цикл, десинхронизированный на 3.3333
мс, поэтому Unity будет отслеживать это.
После 3-го кадра прошло еще 10
мс, но цикл Физики не будет выполняться, начиная с 10+3.3333 = 13.3333
, который все еще ниже, чем fixedDeltaTime
. Теперь давайте предположим, что 4-й кадр рендеринга "идет не так" и длится 25
мс вместо просто 10
. В начале следующего цикла по физике с момента последнего обновления физики прошло 25+13.3333 = 38.3333
, а 38.3333/16.6667 = 2.3
, и Unity выполнит два цикла по физике подряд, чтобы не отставать от фиксированного пошаговое моделирование, прежде чем приступить к визуализации 5-го кадра.
После всего этого вступления давайте вернемся к вашей проблеме и посмотрим, что происходит:
В определенный момент вы выполняете Update()
и устанавливаете _jumpRequest = true;
и _fallRequest = true;
.
После этого кадра рендеринга FixedUpdate()
выполняется впервые, выполняя строку AddForce ForceMode.VelocityChange
и устанавливая _fallRequest = false;
, _jumpGravitySent = false;
и _keepOnJumping = false;
. После окончания этого FixedUpdate()
Unity выполняет физическое моделирование, регулируя положение и скорости твердого тела благодаря физическому движку.
Теперь возникает проблема: поскольку кадр рендеринга был медленным, физический цикл выполняется, по крайней мере, два раза подряд, но между ними не выполняется Update()
, поэтому все в FixedUpdate()
пропускается, но симуляция физики во второй раз, перетащите позицию жесткого тела вниз по отношению к намеченной, самой верхней позиции.
Когда Update()
выполняется снова, наконец, ваш код устанавливает _keepOnJumping = true;
, и когда он возвращается к FixedUpdate()
, он выполняет AddForce ForceMode.Acceleration
, но сразу после этого, во второй раз выполняется другое физическое моделирование (из-за низкой частоты кадров), перетаскивая жесткое тело вниз, прежде чем его можно будет отобразить на экране.
Надеюсь, что это поможет понять вашу проблему и почему это происходит, так что теперь у вас есть нужные инструменты, чтобы исправить ее правильно.