Прыжки в Unity от AddForce

Недавно я начал работать с физикой в ​​Unity, и мне нужно, чтобы мой персонаж прыгал.
Я хочу сделать это до AddForce(), но мне также нужно проверить, заземлен ли персонаж.
В коде проверяю со временем.
Вот мой код:

private void JumpByForce() 
{
    time_after_jump = Time.time + 1f;
    Debug.Log(time_after_jump);

    if (Time.time > time_after_jump)
    {
        isJumping = true;
    }
    if (isJumping)
    {
        Player.GetComponent<Rigidbody2D>().AddForce(new Vector2(0, 750));
        isJumping = false;
    }
}

private void Start()
{
    Player_pos_x = Player.transform.position.x;
    Player_pos_y = Player.transform.position.y;
    isJumping = true;
    
}

Я думал, что написал правильный код, но в console не появляется то, что я хочу.
(Печать time_after_jump без добавления + 1f).
В первый раз, когда я нажимаю кнопку прыжка, игрок прыгает правильно. Но в следующие разы он не прыгает.
Мой самый большой вопрос - почему time_after_jump печать без
(+ 1f)?

Можете ли вы показать код, в котором вы вызываете метод JumpByForce()?

Pavlos Mavris 04.04.2023 09:00

Если вы добавите 1f ко времени и назначите его для time_after_jump, то это будет отображаться в отладке, только с уже примененным 1f. Т.е., б = 2; a = b + 1. Отладка покажет как 3, а не a + 1 (или 2+1).

DylanT 25 04.04.2023 09:03
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
70
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Debug.Log() печатает конечное значение, а не выражение в переменной. В вашей ситуации он печатает окончательное значение time_after_jump. Unity вычисляет это значение в предыдущей строке, а затем печатает его (поэтому вместо 10+1 печатается 11).

Кроме того, причина, по которой ваш игрок не прыгает после первого раза, заключается в том, что Time.time никогда не будет больше time_after_jump, поскольку вы добавляете к нему 1 перед проверкой, поэтому первое if никогда не срабатывает, и, следовательно, isJumping никогда не бывает истинным, за исключением в первый раз, когда вы инициализируете его значением true.

Да, это то, что мне нужно. Мне нужно сохранить окончательное значение этого выражения (time_after_jump = Time.time + 1f;) и проверить, больше ли Time.time, чем time_after_jump

Hayk 04.04.2023 11:43

@Hayk Time.time никогда не будет больше time_after_jump, потому что вы присваиваете ему более высокое значение перед проверкой.

Tom Sebty 04.04.2023 11:53

Если я даю time_after_jumpTime.time + 1f выражение СРАЗУ, а Time.time продолжает добавлять его значение, почему оно никогда не будет больше, чем time_after_jump?

Hayk 04.04.2023 12:03

Поскольку эта функция не работает при обновлении (и даже если бы она работала, она бы не работала, потому что при каждом вызове time_after_jump инициализируется больше, чем Time.time. Кроме того, Time.time не добавляет к его значению, вы просто получаете текущее время от него.

Tom Sebty 04.04.2023 20:14

Спасибо за тщательное объяснение. я решил эту проблему

Hayk 05.04.2023 07:27

Я считаю, что я понял проблему здесь. if (Time.time > time_after_jump) а всегда возвращайтесь false.

Допустим, Time.time = 2. И time_after_jump = Time.time + 1. Тогда time_after_jump = 3. Это означает, что оно всегда больше.

Попробуйте это вместо этого:

time_after_jump = Time.time;
Debug.Log(time_after_jump);

if ((Time.time + 1f) > time_after_jump)
{
    isJumping = true;
}

Хотя лично я бы использовал time.deltaTime, создал таймер и сбрасывал значение таймера при прыжке, чтобы установить isJumping в false.

Например:

time_after_jump += Time.deltaTime; 
if (time_after_jump > timeJumping)
{
  isJumping = true;
}

if (isJumping)
{
   //Movement here
   time_after_jump = 0;
   isJumping = false;
}

Однако это было бы намного проще, если бы вы использовали вход для прыжка. Затем вы сбросите таймер при нажатии прыжка.

Нахожусь на работе, так что это не проверено, но я надеюсь, что вы поняли идею. Удачного кодирования.

В вашем примере вы упомянули это правильно, но в time_after_jump мне нужно сохранить постоянное значение, а затем проверить, превышает ли Time.timetime_after_jump. time_after_jum сохранение значения Time.time (например, 2), а затем добавление 1f к этому значению (резюме time_after_jump сохранение 3f), но Time.time не является постоянным. Оно будет повышаться до тех пор, пока не станет выше time_after_jump. И как я понял time_after_time сохраняю это значение один раз, когда нажимаю на кнопку, которая активирует JumpByForce() функцию.

Hayk 04.04.2023 11:37

Вот почему я бы добавил к переменной (+=) вместо присваивания (=), чтобы вы могли сбросить переменную до 0. Time.time будет продолжать увеличиваться во время игры. То, как это настроено, вам нужно будет минусовать от time_after_jump после каждого перехода, но если функция вызывается из обновления, она будет постоянно устанавливать time_after_jump на Time.time, что + 1 всегда будет больше, и is_jumping всегда будет правдой.

DylanT 25 04.04.2023 11:47

Функция вызывается при нажатии на кнопку, и мне не нужно делать переменную 0 time_after_jump. В любом случае, я получаю значение Time.time и добавляю его 1f независимо от того, что Time.time будет

Hayk 04.04.2023 11:59

Чтобы персонаж прыгал по AddForce со временем, я должен проверить time_after_jump в методе FixedUpdate и если Time.time будет больше time_after_jump, то isJumping будет верным и я снова смогу прыгать нашим персонажем.

Я использовал этот код:

private void JumpByForce() 
{
    if (isJumping)
    {
        time_after_jump = Time.time + 0.8f;
        Player.GetComponent<Rigidbody2D>().AddForce(new Vector2(0, 750));
        isJumping = false;
    }
}

private void FixedUpdate()
{
    if (Time.time > time_after_jump)
    {
        isJumping = true;
    }
}

Другие вопросы по теме