Камера следит за дрожанием Rigidbody каждые несколько секунд с объектами фона
Камера следит за джиттером Rigidbody2D каждые несколько секунд с фоновыми (нежесткими) объектами (препятствиями). FPS в профилировщике в порядке, он близок к 100. Также возможна интерполяция. Использование Unity 2017.4.12 (LTS)
GIF GIF Видео здесь
Camera Follow Script
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);
}
}
Игрок
0 ответов
Скорость, с которой FixedUpdate
называется отличается от частоты кадров, которая диктует скорость, с которой Update
а также LateUpdate
называются.
FixedUpdate
следует использовать для установки скоростей на твердых телах. Установка позиций в 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: Кинематическое твердое тело 2D
Ridgedbody2D с Body Type
установить Kinematic можно безопасно перемещать с помощью компонента MovePosition компонентов Ridgedbody2D. Таким образом, с этой настройкой ваш скрипт игрока будет выглядеть так: public class 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 здесь, потому что значение, возвращаемое этим свойством, всегда будет правильным временем дельты для типа метода Update, в котором он используется.
Следующая камера
Обновление положения камеры всегда должно синхронизироваться с частотой кадров. Это может привести к заиканию в FixedUpate. Вместо этого это должно быть сделано в Update
или (если вы хотите, например, подождать, пока не изменится положение из-за анимации, прежде чем устанавливать положение) в LateUpdate
наконец
Если бомбы в игре также движутся и представляют собой Ridgidbody, положение которых обновляется аналогично в их FixedUpate, вы должны изменить их, чтобы использовать решение, как описано в любом из двух вариантов использования.
Обратите внимание, что кинематические жесткие тела не будут вызывать каких-либо событий столкновения (триггерные события будут по-прежнему вызываться). Если вы хотите переместить и бомбы, и плоскость как кинематические жесткие тела, но события столкновения все еще должны быть причиной, вы можете установить Use Full Kinematic Contacts
на твердых телах, которые должны получать эти обновления. Я не уверен, окажет ли это какое-либо влияние на производительность (кроме того, которое генерирует эти события), и вы все равно можете прочитать 1 [полную документацию по компоненту Ridigbody2D].
В целом TL; DR: то, что вы видите, скорее всего, не проблема производительности (или она будет отображаться в Профилировщике, и у вас будет трепетать и хуже FPS), а дрожание движения из-за использования неправильных методов и схем обновления для применения движения к физическим телам. Это очень распространенная ошибка в Unity.
Если есть проблемы с производительностью, приложите скриншот профилировщика. С помощью метода отображения FPS, который вы используете, скорее всего, вы часто запускаете GC.Collect для манипуляций со строками в сценарии FPS (и GC.Allocs в других местах).