RigidBody2D AddForce не добавляет ускорения

Я пытаюсь добавить ускорение к объекту с помощью компонента RigidBody2D, используя AddForce, но, похоже, все, что он делает, это вместо этого добавляет фиксированную скорость.

Вот настройки RigidBody2D: Настройки RigidBody2D

Для тестирования я изменил функцию Update, чтобы я мог добавлять силы и периодически сообщать скорость объекта:

void Update()
{
    time += Time.deltaTime;
    if (time > 0.5)
    {
        Debug.Log("Velocity magnitude = " + rigidbody2D.velocity.magnitude);
        time = 0;
    }

    if (Input.GetKeyDown(KeyCode.Q))
    {
        rigidbody2D.AddForce(Vector2.right);
    }
}

Я вижу, что каждый раз, когда я нажимаю Q, величина скорости увеличивается на фиксированные 0,02.

Т.е. сначала он вообще не движется и скорость равна 0, затем после нажатия Q величина скорости изменяется на 0,02 и остается на 0,02, в то время как объект медленно перемещается вправо. Повторное нажатие Q увеличивает его до 0,04, затем повторное нажатие увеличивает его до 0,06 и так далее.

Это результаты, полученные два дня назад. Сегодня я снова проделал эксперимент и получил другие приращения скорости, но в остальном то же самое поведение.

Скорость меняется только когда я добавляю силу.

Если бы я добавил силу величиной 1 к покоящемуся объекту с массой 1, то его скорость увеличивалась бы на 1 по величине каждую единицу времени (что, я думаю, здесь составляет секунды).

Вместо этого он остается неизменным.

Использование ForceMode2D.Impulse увеличивает приращение скорости с 0,02 до 1, но поведение остается прежним - без ускорения, только одноразовые приращения скорости.

Что я делаю неправильно?


Я пробовал искать похожие сообщения и проблему в целом, но единственное, что я обнаружил, были либо неуместными, либо спрашивали противоположное (как остановить ускорение).

Любая помощь будет оценена по достоинству.

Версия Unity - 2019.1.1f1.


person Tomer Godinger    schedule 05.08.2019    source источник


Ответы (2)


TL;DR

Что вы делаете неправильно, так это то, что ожидаете неправильного физического поведения от функции приложения силы. Эта функция делает то, что говорит, она применяет силу. Он мгновенно изменяет скорость объекта, добавляя к нему. Силовой режим для двухмерных тел только указывает двигателю учитывать массу объекта или нет.

Проблема в том, что Unity использует наименования, AddForce не «добавляет» силу, а просто применяет силу для одного кадра. На следующих кадрах все силы снова равны нулю. Если вы хотите сохранить силу, просто создайте свой собственный вектор в своем скрипте, измените его и примените его к объекту в каждом кадре с помощью AddForce.


как дела?

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

С другой стороны, ускорение - это приложенная постоянная сила, подумайте об этом. Если ваша машина неподвижна, и вы толкаете ее в течение короткого промежутка времени, она двинется, а затем остановится. С другой стороны, если вы продолжите толкать, добавляя все больше и больше силы, машина будет двигаться все быстрее и быстрее. Теперь подумайте о своем окружении: у вас есть объект без трения. Каждый раз, когда вы нажимаете Q, вы добавляете к нему небольшую силу. Он движется вправо немного быстрее, но с постоянной скоростью (нет силы изменять его скорость).

Вот что бы вы хотели сделать. Вместо того, чтобы добавлять силу только в кадре, в котором вы нажали Q, добавляйте, пока вы нажимаете Q. Это то, что вы хотите сделать:

private void FixedUpdate()
{
    time += Time.deltaTime;
    if (time > 0.5)
    {
        Debug.Log("Velocity magnitude = " + rigidbody2D.velocity.magnitude);
        time = 0;
    }

    if (Input.GetKey(KeyCode.Q))
    {
        rigidbody2D.AddForce(speedMultiplier * Time.fixedTime * Vector2.right, ForceMode2D.Force);
    }
}

Еще одна проблема - это именование, которое использует Unity, AddForce не «добавляет» силу, а просто применяет силу для одного кадра. На следующих кадрах все силы снова равны нулю. Если вы хотите сохранить силу, просто создайте свой собственный вектор в своем скрипте, измените его и примените его к объекту в каждом кадре с помощью AddForce.

Также видите, что я изменил обновление на FixedUpdate? В Unity вместо этого рекомендуется применять все изменения физики в этом методе. Обновление запускается столько, сколько может (если возможно, один раз в каждом кадре), фиксированное обновление вместо этого запускается только после завершения физического потока. Это означает, что вы не тратите время процессора, говоря объекту, чтобы он двигался каждый кадр, а вместо этого ждете, пока физика будет синхронизирована.

person Lucas Montenegro Carvalhaes    schedule 05.08.2019
comment
Привет, спасибо за ваше предложение и отзыв о FixedUpdate. К сожалению, проблема сохраняется только с разными числами (я не использовал speedMultiplier, так что это похоже на speedMultiplier = 1). Я предполагал, что сила означает то же самое, что и в физике. Второй закон Ньютона гласит, что F = m * a, поэтому при m = 1 я ожидал, что F = a. Может быть, сила приложена только к одному кадру? Как мне заставить его сохранить ту силу, которую я добавил? Кстати, ForceMode2D.Force является значением по умолчанию. Увеличение масштаба силы тяжести (изначально 0) добавляет ускорение вниз, но не меняет поведение оси x. - person Tomer Godinger; 05.08.2019
comment
Я просто предположил, что у вас нет гравитации, поскольку вы сообщили, что ваш объект движется с постоянной скоростью. Если бы у вас была сила тяжести и пол, у вас было бы трение, которое противодействовало бы этому движению. - person Lucas Montenegro Carvalhaes; 05.08.2019
comment
Я использую GetKey вместо GetKeyDown. Попробуйте удерживать Q;) - person Lucas Montenegro Carvalhaes; 05.08.2019
comment
Также то, что F = m.a означает, что мгновенная сила объекта может быть рассчитана как его масса, умноженная на его ускорение. Это не значит, что сила равна ускорению. В данный момент количество силы, которой подвергается объект, может быть вычислено с помощью этого выражения. - person Lucas Montenegro Carvalhaes; 05.08.2019
comment
Я приложил снимок экрана с настройками RigidBody, который показывает, что для Gravity Scale установлено значение 0. У меня нет пола, но это совсем не важно. Гравитация тянет вниз, я добавляю силу справа, которая ортогональна ей, поэтому они действуют независимо. Трение только уменьшает активные силы. Проблема здесь в том, что AddForce не добавляет физическую силу к телу с самого начала. Наличие чего-то, что можно было бы противостоять силе, которую я пытаюсь добавить, конечно же, ничем не поможет. - person Tomer Godinger; 05.08.2019
comment
F = m * a означает, что сумма всех сил, действующих на тело в данный момент времени, дает вектор в том же направлении, что и ускорение этого тела в тот момент, возможно, с другой величиной (разница в масштабе - это масса тела ). Пока сумма сил на теле не равна нулю, оно ускоряется. Я добавляю силы. Я не добавляю силы противодействия. Сумма сил не должна быть нулевой. Значит, должно быть ускорение. Нет. Либо сила удаляется сама по себе, либо физическая система не подражает ньютоновской физике, ни то, ни другое, я думаю, не является верным, поэтому мой вопрос здесь. - person Tomer Godinger; 05.08.2019
comment
Использование GetKey вместо GetKeyDown только ускоряет прибавку к скорости. Объект по-прежнему имеет фиксированную скорость, когда я не удерживаю клавишу Q, чего не должно быть, если к нему приложено ненулевое усилие. - person Tomer Godinger; 05.08.2019
comment
Как я уже сказал, я рассматривал гравитацию только потому, что хотел понять, почему ваш объект не ведет себя так, как обычный физический объект. Инерция сохраняла свою скорость, поэтому я сказал, что ваш объект не имеет трения. Я никогда ничего не говорил о применении трения. Я просто пытался понять вашу настройку (это невозможно с помощью одного снимка экрана). - person Lucas Montenegro Carvalhaes; 05.08.2019
comment
Кроме того, вы, кажется, не понимаете, как работают движки или игровые циклы. Вы не добавляете силу ни к чему, вы применяете силу к объекту для одного кадра. Эта сила нигде не хранится. Если вам нужно такое поведение, просто сохраните вектор и суммируйте с ним свою силу, а затем применяйте этот вектор в каждом кадре к объекту как силу. - person Lucas Montenegro Carvalhaes; 05.08.2019
comment
чего не должно быть, если он имеет ненулевое значение. К нему не прилагаются никакие силы. Вы только прикладываете силу в рамке Q, нажатой. Просто прочтите мой ответ, там все есть. - person Lucas Montenegro Carvalhaes; 05.08.2019
comment
Подождите минуту. Вы хотите сказать, что каждый кадр начинается со всех физических сил, равных 0 для каждого объекта? Я предположил, что AddForce добавляет силу этому объекту и применяется с этого момента. Если это так, то это прекрасно объясняет, что происходит. Однако такая информация действительно должна быть в документации по функциям. знак равно - person Tomer Godinger; 05.08.2019
comment
Точнее, сила добавляется мгновенно, а не сохраняется на объекте. Если вы хотите сохранить силу, просто сохраните вектор и добавьте к нему, применяя его к объекту при каждом фиксированном обновлении. - person Lucas Montenegro Carvalhaes; 05.08.2019
comment
Хорошо, это все объясняет. Спасибо. Я добавлю еще один ответ с этим битом, так как это объяснение, и, конечно же, вам за это спасибо. знак равно - person Tomer Godinger; 05.08.2019
comment
Без проблем ;) . Можете ли вы отметить мой ответ как правильный? Добавлю туда разрешение. - person Lucas Montenegro Carvalhaes; 05.08.2019
comment
Конечно. Просто переместите второй абзац, который вы там написали, вверх с заголовком TL; DR и разделителем после него, чтобы людям с той же проблемой было легко понять суть, не читая все. - person Tomer Godinger; 05.08.2019

Я не думаю, что это добавит объекту силы, достаточной для его движения. Обычно вам нужно умножить ваше направление на коэффициент силы. Попробуйте что-нибудь вроде rigidbody2D.AddForce(Vector2.right * 1000);. То есть внутренне, вероятно, слишком большая сила, но, по крайней мере, вы будете знать, что она движется.

person Brandon Miller    schedule 05.08.2019
comment
Я просто сделал это и получил тот же результат, только с разными числами. На этот раз величина скорости увеличилась с 0 до 120, а затем увеличивалась на 140 каждый раз, когда я нажимал Q (120 - ›260 -› 400 - ›540 -› 680). Это изменилось только когда я нажал клавишу Q. Честно говоря, я не ожидал другого, поскольку мой первый эксперимент показал, что он движется, хотя и медленно. Скорость изменилась, но только в фиксированных значениях, как я объяснил. Тем не менее, спасибо за ваше предложение. - person Tomer Godinger; 05.08.2019