2017-02-16 20 views
3

Я знаю, если я сделаю слишком много вещей в update(), последствием будет снижение частоты кадров ниже целевой частоты кадров. Но что произойдет, если я сделаю то же самое в fixedUpdate()?Что является следствием выполнения тяжелой работы в fixedUpdate()?

Может ли это привести к тому, что Unity's PhysicsEngine испортится, или это приведет к сбою программы?

+1

Некоторые хорошие ответы [здесь] (http://answers.unity3d.com/questions/202614/and-yet-more-questions-about-fixedupdate.html) и [здесь] (Http: // answer.unity3d.com/questions/10993/whats-the-difference-between-update-and-fixedupdat.html) – DeclanPossnett

+0

@DeclanPossnett Таким образом, если у меня есть 20ms default fixedTimeFrame и мой fixedUpdate() принимают 100 мс для запуска , игровой мир будет двигаться в 5 раз медленнее, чем он должен? – AVAVT

+1

В основном ответ _best_ на [этот вопрос об объединении] (http://answers.unity3d.com/questions/10993/whats-the-difference-between-update-and-fixedupdat.html) объясняет, что вы обычно получаете желаемое количество обновлений для каждого кадра естественно в Unity, но если вы наложите такую ​​большую нагрузку на физический движок, на самом деле он бы не догнал частоту кадров, поэтому не смог имитировать! – DeclanPossnett

ответ

3

Ответы и комментарии были очень полезными, но им не хватает четкого, содержательного ответа на мой вопрос. Всем известно, что плохие вещи произойдут, когда вы установите слишком большую нагрузку в цикле FixedUpdate(), мой вопрос должен был задать то, что произойдет.

Поскольку я, наконец, получил свою руку на компьютере, я решил сделать некоторые тесты самостоятельно. Только для справки это то, что я тестировал:

public class TestFixedUpdate : MonoBehaviour { 
    public int loopNo = 500000; 

    private int noOfCall = 0; 
    private int collisionTimes = 0; 

    private void FixedUpdate() 
    { 

     if (noOfCall > 100) return; 
     float time = Time.timeSinceLevelLoad; 

     for (int i = 0; i < loopNo; i++) { 
      Quaternion.Slerp(Quaternion.identity, Quaternion.FromToRotation(Vector3.up, Vector3.forward), Mathf.Abs(Mathf.Sin(Time.timeSinceLevelLoad))); 
     } 

     Debug.Log(Time.timeSinceLevelLoad.ToString("0.00")); 

     if (noOfCall > 99) Debug.Log("Simulation finished. Times collided:" + collisionTimes); 

     noOfCall++; 
    } 

    private void OnCollisionEnter(Collision collision) 
    { 
     if (noOfCall > 100) return; 
     collisionTimes++; 
     Debug.Log("Times collided:" + collisionTimes); 
    } 
} 

Я положил его на сферу, которая будет непрерывно отскакивать на плоскости. Тест проводился путем изменения функции от FixedUpdate() и Update() и сравнения различий.

Основное различие, которое я выяснил, заключалось в том, что в случае FixedUpdate() моделирование Unity Time (время игры в мире) откладывается на синхронизацию с фактическим временем. Другими словами, любая функция, зависящая от системы Unity Time, будет действовать так, как если бы весь мир замедлился.

также:

  1. Unity сообщает ту же частоту кадров для обоих случаях, даже если для FixedUpdate() случае, очевидно, что фактическая частота кадров - кадр в реальном мире второй - значительно ниже.

  2. Помимо замедление, обнаружение столкновения и логика моделирования физики, похоже, работают как обычно. Тела, которые должны сталкиваться, все еще сталкиваются; ускорение, применение силы и т. д. все еще работают. Жесткие тела, которые не прыгают через коллайдер в 20 мс (Unity's ms), все еще сталкиваются и возвращаются, как обычно.

  3. Параметр Maximum Allowed Timestep в настройках проекта определяет максимальное количество (время симуляции Unity) до того, как кадр должен быть нарисован (я никогда не знал, для чего это было раньше). Уточнение: если я установил его на 0,5 секунды, то независимо от того, сколько кодов я поместил в обе функции, шаг логического обновления (Update()) вызывается сразу после того, как раунд FixedUpdate() имитирует 0,5-ю секунду, а затем сцена будет быть оказанным.

0

Двигатель будет останавливаться при обработке большой нагрузки (например, если вы выполняете бесконечный цикл) внутри любой функции. Вещи, которые полагаются на Time.DeltaTime, начнут действовать, если частота кадров падает слишком низко. Неважно, будет ли это Update или FixedUpdate.

Что вы можете сделать, если вам нужен процесс для запуска большой нагрузки, это использовать сопрограммы, например. Функция и выход IEnumerator, которая позволяет разделить обработку по нескольким кадрам или вызвать функцию, вызванную обратным вызовом. например если у вас есть контрольный путь AI 5 раз в секунду, вы можете обрабатывать это в окне «Обновление с помощью счетчика» каждый кадр или планировать обратный вызов.

В принципе, существует ограничение на то, сколько кода вы можете запускать на каждый кадр без ухудшения производительности. Умное переписывание должно сделать ненужным. Посмотрите, можете ли вы кэшировать результаты вычислений или предварительно вычислить как можно больше данных вне игры.

 Смежные вопросы

  • Нет связанных вопросов^_^