Как правило, в OnCollisionEnter2D
и OnCollisionExit2D
вы должны проверить, с чем вы сталкиваетесь!
, например, используя теги и CompareTag
как
private void OnCollisionExit2D(Collision2D collision)
{
if(!collision.transform.CompareTag("Ground")) return;
// only do this if the thing you don't collide
// anymore is actually the ground
isGrounded = false;
}
private void OnCollisionEnter2D(Collision2D collision2)
{
if(!collision.transform.CompareTag("Ground")) return;
// only do this if the thing you collided with is actually the ground
isGrounded = true;
}
В противном случае при столкновении со стеной происходит OnCollisionEnter2D
, за которым следует OnCollisionExit2D
=> isGrounded = false;
Также в общем случае: не использовать GetComponent
в Update
и особенно не для получения одной и той же ссылки в 3 разных местах!
Скорее получите его один раз в Awake
или уже назначьте его через инспектора
// already assign via the Inspector by drag&drop
[SerializeField] private Rigidbody2D _rigidbody;
// as fallback assign ONCE in the beginning
private void Awake()
{
if(!_rigidbody) _rigidbody = GetComponent<Rigidbody2D>();
}
и позже использовать его
void Update()
{
moveVelocity = 0;
//Left Right Movement
if (Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.A))
{
// I would use -= and += here so when pressing both buttons
// you simply stay at 0. But that's only my opinion of course
// Alternatively I would use 'else if' in order to make the blocks exclusive
moveVelocity -= speed;
facingEast = false;
}
if (Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.D))
{
moveVelocity += speed;
facingEast = true;
}
_rigidbody.velocity = new Vector2(moveVelocity, _rigidbody.velocity.y);
// here it is cheeper to first check the isGrounded flag
// and only if it is true get the input
if (isGrounded && (Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.Space)))
{
_rigidbody.AddForce(Vector2.up * jumpPower);
}
}