Прежде всего большинство Ваших задач здесь может решать Rigidbody2D. Для понимания, Rigidbody - это система которая реализует физические явления в движке и она подходит для практически любых ситуаций - если станете большим специалистом то может быть найдете решение получше. Обратите внимание, что движение, ускорение свободного падения и столкновение это физические процессы.
Для начинающего лучший курс по физике в Unity.
Вы можете реализовать прыжок, коллизию (столкновения) и движение через Rigidbody.
[RequireComponent(typeof(Rigidbody2D), typeof(SpriteRenderer))]
public class Player : MonoBehaviour
{
[SerializeField, Min(1)] private float _speed = 1;
[SerializeField, Min(1)] private float _jumpForce = 1;
[SerializeField] private LayerMask _ground;
private Rigidbody2D _body;
private SpriteRenderer _player;
private void Start()
{
_body = GetComponent<Rigidbody2D>();
_player = GetComponent<SpriteRenderer>();
}
private void Update()
{
var horizontal = GetHorizontalInput();
var jump = Input.GetKey(KeyCode.W);
if(jump && IsGrounded())
Jump();
Move(horizontal);
Animate();
}
private float GetHorizontalInput()
{
return Input.GetAxis("Horizontal");
}
private bool IsGrounded()
{
return Physics2D.OverlapArea(
GroundCheck.bounds.min,
GroundCheck.bounds.max,
_ground);
}
private void Move(float input)
{
var deltaDistance = Time.deltaTime * _speed;
var deltaPosition = transform.position.x + (deltaDistance * input);
_body.MoveDirection(new Vector2(deltaPosition, 0));
}
private void Jump()
{
_body.AddForce(Vector3.up * _jumpForce)
}
private void Animate()
{
var velocity = _body.velocity.normalized;
if (velocity.x < 0)
{
sr.flipX = true;
}
else if (velocity.x > 0)
{
sr.flipX = false;
}
}
}
В чём разница между Rigidbody.MovePosition и Transform.Translate? Rigidbody управляет физическими явлениями, т.е. трение с поверхностями (когда мы движемся мы трёмся коллайдером), столкновениями и физикой во время прыжка. Когда мы движемся в препятствие и движемся с помощью Rigidbody.MovePosition физический движок замечает, что мы двигаемся в препятствие ну и симулирует реакцию поверхности, ну и мы не проваливаемся в коллайдер за счёт этого. Transform.Translate напрямую меняет позицию объекта, ему довольно безразлична физика и столкновения, он просто меняет позицию, и как вы могли заметить, он может изменить позицию прямо в препятствие.
Резюмируя: Transform.Translate хорош когда нас не волнуют столкновения: UI-анимации, движение облаков, перемещение препятствий на которые ничто не влияет физически. В остальных случаях Rigidbody.MovePosition.
Остальные детали,
* Если используем GetComponent значит надо гарантировать наличие компонента через RequireComponent. Когда компонентов становится больше, а ты такие вещи не предусмотрел однажды ты можешь словить 100+ Null reference exception в консоль
* Параметрам можно установить минимальные возможные значения через атрибут Min, таким образом случайно нельзя будет допустить неверное поведение
* Стирай изначальные комментарии и явно пиши private на методах, таким образом читается быстрее, лишнее внимание переводить не придётся
* gameObject.GetComponent не обязательно, можно просто GetComponent
* Вместо Update уместнее FixedUpdate. Разница в том, что FixedUpdate ВСЕГДА вызывается каждый определенный промежуток времени, в отличие от Update. В курсе наверху описывается почему так лучше, и разница между FixedUpdate и Update.
* Проверять нахождение на земле где-то читал предлагали с помощью
рейкаста, стоит помнить что любой физический метод имеет 2D версию, которая тебе лучше подходит
* Научись придерживаться одного и того же стиля во всём своём коде
* Метод должен быть глаголом или словосочетанием с глаголом