Что я обычно делаю, так это проверяю, иду ли я вверх или вниз. Я принимаю только проверку земли, если иду вниз.
void OnCollisionEnter(Collision other)
{
if (other.gameObject.name == "Ground" && rb.velocity.y < 0)
{
canJump = true;
}
}
Тем не менее, вы используете getKeyDOWN
, поэтому речь идет не о удержании места и т. Д.
Итак, следующее, что я могу порекомендовать, это: установить speed.y на 0 перед прыжком.
if (Input.GetKeyDown("space"))
{
Vector3 vel = rb.velocity;
vel.y = 0;
rb.velocity = vel;
rb.AddForce(0, 10, 0, ForceMode.VelocityChange);
// ...
}
edit : Подождите, моя первая мысль была «он использует getKey и держит пробел», моя вторая мысль была: «он пропустил Time.deltaTime». Но теперь я вижу это:
Вы использовали Input.Get...
в FixedUpdate!
Позвольте мне объяснить:
Все входы оцениваются перед вызовом всех Update
.
Как вы можете видеть в Порядке выполнения Входные события обрабатываются непосредственно перед обновлением.
Теперь, в зависимости от частоты кадров, обновление вызывается часто или редко, по сравнению с (почти) постоянной FixedUpdate.
Таким образом, FixedUpdate может вызываться несколько раз между Update
вызовами. А это значит, что входные события запускались один раз.
ТАК Я должен предположить, что Input.GetKeyDown(Key.SPACE)
будет истинным в нескольких FixedUpdates!
Легко исправить:
bool jump_pressed = false;
void Update()
{
if(Input.GetKeyDown("space"))
{
jump_pressed = true;
}
if(Input.GetKeyUp("space"))
{
jump_pressed = false;
}
}
void FixedUpdate()
{
if(jump_pressed)
{
jump_pressed = false;
rb.AddForce(0, 10, 0, ForceMode.VelocityChange);
// etc...
}
}
Таким образом, вы просто обрабатываете всю логику ввода в обновлении, а остальные выполняете в фиксированном обновлении.
Конечно, jump_pressed нужно установить в false в FixedUpdate, потому что в противном случае он останется истинным несколько раз FixedUpdate.
edit2 : Я снова посмотрел ваш код. Что бы вы ни делали, независимо от того, находится ли оно в FixedUpdate или Update, не используйте Time.deltaTime
в AddForce
.
AddForce будет манипулировать скоростью. И скорость используется в каждом PhysicsUpdate для перемещения преобразования. Но PhysicsUpdate / FixedUpdate пытается работать с (почти) фиксированной скоростью, тогда как Time.deltaTime дает вам истекшее время последнего (Обновления) кадра.
Если вы перемещаете преобразование самостоятельно (position +=
...) - используйте Time.deltaTime. Но не используйте его, когда используете AddForce.