Камера следит за дрожанием Rigidbody каждые несколько секунд с объектами фона - PullRequest
0 голосов
/ 08 октября 2018

Камера следит за джиттером Rigidbody2D каждые несколько секунд с фоновыми (нежесткими) объектами (препятствиями).FPS в профилировщике в порядке, он близок к 100. Также возможна интерполяция.Использование Unity 2017.4.12 (LTS)

GIF GIF Видео здесь

Сценарий следования камеры

 public class CameraFollow : MonoBehaviour {
        public float followRange = 0.5f;
        public float cameraZ;
        public Transform Player;
        public Vector3 newPos;
        void Start () {
            cameraZ = transform.position.z;
        }
        void FixedUpdate() {
            newPos = new Vector3(Player.position.x + followRange, 0, cameraZ);
            transform.position = Vector3.Lerp(transform.position, newPos, 0.5f);
        }   
    }

Сценарий игрока:

public class PlayerBall : MonoBehaviour {

    public float xSpeed = 10;

    // Update is called once per frame
    void FixedUpdate () {
        this.transform.position = new Vector3(this.transform.position.x + Time.fixedDeltaTime * xSpeed, 
            this.transform.position.y , transform.position.z);
    }

}

Player Rigidbody

enter image description here

Загрузка файла проекта

1 Ответ

0 голосов
/ 05 февраля 2019

Скорость, с которой вызывается FixedUpdate, отличается от частоты кадров, которая определяет скорость, с которой вызываются Update и LateUpdate.

FixedUpdate следует использовать для установки скоростей наrigidbodies.Установка позиций в FixedUpdate всегда создает риск дрожания, так как он вызывается не синхронно с вашей частотой кадров.Установка положения на смоделированном Rigidbody также идет вразрез с точкой его моделирования, поскольку вы переопределяете любое влияние, которое физика может оказать на Rigidbody.

Страница Руководства для Ridgidbody 2D также утверждает, что:

Компонент Rigidbody 2D переопределяет Transform и обновляет его до положения / поворота, определенного в Rigidbody 2D.Обратите внимание, что, хотя вы все равно можете переопределить Rigidbody 2D, изменив компонент Transform самостоятельно (поскольку Unity предоставляет все свойства для всех компонентов), это приведет к таким проблемам, как объекты GameObject, проходящие через или друг к другу, и непредсказуемому движению.

[...] Коллайдер 2D никогда не следует перемещать напрямую, используя Transform или любое смещение коллайдера;вместо этого следует переместить Rigidbody 2D.Это обеспечивает наилучшую производительность и обеспечивает правильное обнаружение столкновений.

Для твердого тела, которое должно двигаться, у вас есть выбор между использованием Dynamic BodyType или Kinematic, в зависимости отваш случай использования.Если вы хотите, чтобы самолет перемещался другими нестатическими коллайдерами, он должен быть динамическим.Если его не нужно перемещать, он должен быть Kinematic (который также более производительный).

Вариант использования 1: Dynamic Rigidbody 2D

Это настройка, которая установлена ​​на данный момент.Однако на странице руководства для Ridgidbody 2D также указано, что:

Не используйте компонент Transform для установки положения или поворота Dynamic Rigidbody 2D.Моделирование перемещает Dynamic Rigidbody 2D в соответствии с его скоростью;Вы можете изменить это напрямую с помощью сил, примененных к нему с помощью сценариев, или косвенно с помощью столкновений и гравитации.

Таким образом, вы должны изменить сценарий Player, чтобы использовать метод Rigidbody2D AddForce

public class PlayerBall : MonoBehaviour {

  public float thrust = 10;
  Rigidbody2D body;
  Vector2 forwardDirection = Vector2.right;

  void Awake() {
    body = GetComponent<Ridigbody2d>();
  }

  // FixedUpdate is called once per physics update
  void FixedUpdate () {
    body.AddForce(forwardDirection * thrust)
  }

}

Теперь это просто будет постоянно добавлять силу к плоскости, продвигая ее вперед и ускоряя.Таким образом, вы, вероятно, захотите найти способ стабилизировать скорость, уменьшая добавленную силу по мере приближения к целевой скорости (вы можете проверить текущую скорость с помощью body.velocity.x) и замедляя плоскость с помощью drag.

Я не буду вдаваться в детали, потому что подозреваю, что Kinematic - это то, что вам нужно:

Вариант использования 2: Kinematic Rigidbody 2D

ARidgedbody2D с Body Type, установленным на Kinematic, можно безопасно перемещать с помощью компонента Ridgedbody2D MovePosition .Таким образом, при такой настройке сценарий проигрывателя будет выглядеть следующим образом: открытый класс PlayerBall: MonoBehaviour {

  public float xSpeed = 10;
  Rigidbody2D body;
  Vector2 forwardDirection = Vector2.right;

  void Awake() {
    body = GetComponent<Ridigbody2d>();
  }

  // FixedUpdate is called once per physics update
  void FixedUpdate () {
    body.MovePosition(forwardDirection + xSpeed * Time.deltaTime)
  }

}

Примечание: здесь я использую Time.deltaTime, поскольку значение, возвращаемое этим свойством, всегда будетправильное время дельты для типа метода обновления, в котором он используется.

После камеры

Обновление положения камеры всегда должно синхронизироваться с частотой кадров.Это может привести к заиканию в FixedUpate.Вместо этого это должно быть сделано в Update или (если вы хотите, например, подождать, пока изменения позиции из-за анимации не будут применены, прежде чем устанавливать позицию) в LateUpdate

И наконец

ЕслиБомбы в игре также движутся и являются ригидителами, где положение обновляется аналогично в их FixedUpate, вы должны изменить их, чтобы использовать решение, как описано в любом из двух вариантов использования.

Обратите внимание, что Kinematic Rigididity невызывать любые события столкновения (события триггера будут по-прежнему вызываться). Если вы хотите переместить бомбы и плоскость как кинематические риджитела, но события столкновения все еще должны быть причиной, вы можете установить Use Full Kinematic Contacts для жестких тел, которые должны получать эти обновления.Я не уверен, окажет ли это какое-либо влияние на производительность (кроме того, которое генерирует эти события), и вы все равно можете прочитать 1 [полную документацию по компоненту Ridigbody2D].

Общий TL; DR : то, что вы видите, скорее всего, не проблема производительности (или она будет отображаться в Профилировщике, и у вас будет трепетать и хуже FPS), но движениедрожание из-за использования неправильных методов и схем обновления для применения движения к физическим телам.Это очень распространенная ошибка в Unity.

Если есть проблемы с производительностью, приложите скриншот профилировщика.При использовании метода отображения FPS, который вы используете, скорее всего, вы часто запускаете GC.Collect для манипуляций со строками в сценарии FPS (и GC.Allocs в других местах).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...