void MoveVertical() { bool isCurrentlyJumping = startedToListen && state.IsJumping(); if (grounded && jumpReady && isCurrentlyJumping) { grounded = false; jumpReady = false; verticalSpeed = jumpSpeed; } if (canAirJump && !grounded && airJumpReady && isCurrentlyJumping) { airJumpReady = false; verticalSpeed = jumpSpeed; } float previousVerticalSpeed = verticalSpeed; verticalSpeed -= gravity * Time.fixedDeltaTime; float verticalSpeedAirturnMoment = .15f; if (!airturned && (previousVerticalSpeed >= verticalSpeedAirturnMoment) && (verticalSpeed <= verticalSpeedAirturnMoment)) { animator.StartAnimation(Animation.AIRTURN, state.GetDirection(), () => { airJumpReady = true; airturned = true; }); } if (verticalSpeed < maximumVerticalDropSpeed) { verticalSpeed = maximumVerticalDropSpeed; } Vector2 movementVector = new Vector2(0, verticalSpeed); RaycastHit2D hit = Physics2D.BoxCast(collider.bounds.center, collider.bounds.size, 0, movementVector, Mathf.Abs(movementVector.y), LayerMask.GetMask(collisionLayers)); bool wasGrounded = grounded; if (hit.collider != null) { bool touchedFloor = false; float maximumDistance = movementVector.y < 0 ? -hit.distance + safetyRing : hit.distance - safetyRing; if (hit.distance == 0) { movementVector = new Vector2(0, 0); touchedFloor = true; } else if (Mathf.Abs(maximumDistance) < Mathf.Abs(movementVector.y)) { movementVector = new Vector2(0, maximumDistance); touchedFloor = true; } if (touchedFloor) { if (verticalSpeed < 0) { grounded = true; } verticalSpeed = 0f; } else { grounded = false; } } else { grounded = false; } if (grounded && !wasGrounded) { if (airturned) { airturned = false; animator.StartAnimation(Animation.LANDING, state.GetDirection()); } else { jumpReady = true; } airJumpReady = false; } Move(movementVector); if (grounded) { RaycastHit2D[] floorHits = Physics2D.BoxCastAll(collider.bounds.center, collider.bounds.size, 0, Vector2.down, safetyRing, LayerMask.GetMask(collisionLayers)); foreach (RaycastHit2D floorHit in floorHits) { if (floorHit.collider != null) { if (floorHit.rigidbody != null) { InteractionBase interact = floorHit.rigidbody.GetComponent <InteractionBase>(); if (interact != null) { Influence(interact.Do()); } } } } } }