Exemple #1
0
        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());
                            }
                        }
                    }
                }
            }
        }