Пример #1
0
 private void Awake()
 {
     myVelocity = Vector2.zero;
     // Setting up references.
     priv_Anim           = GetComponent <Animator>();
     priv_Rigidbody2D    = GetComponent <Rigidbody2D>();
     quickCapsule        = GetComponent <CapsuleCollider2D>();
     crouchCheckPosition = new Vector3(
         quickCapsule.offset.x * Mathf.Abs(transform.lossyScale.x),
         (quickCapsule.offset.y + quickCapsule.size.y * 0.0125f) * transform.lossyScale.y,
         transform.position.z);
     crouchCheckSize = new Vector2(
         quickCapsule.size.x * 0.95f * Mathf.Abs(transform.lossyScale.x),
         quickCapsule.size.y * 0.975f * transform.lossyScale.y);
     crouchCheckDirection = quickCapsule.direction;
     //not necessary, but initializing the enums here to make myself feel better
     stateGrounded      = PlayerStateGrounded.Idle;
     stateAerial        = PlayerStateAerial.No;
     stateCrouch        = PlayerStateCrouch.No;
     myOriginalMaxSpeed = myMaxSpeed;
 }
Пример #2
0
        public void Move(float move, bool crouch, bool jump, bool jumpHold)
        {
            CollisionChecks();
            if (priv_Grounded && Physics2D.OverlapCapsule(
                    GetCrouchCheckPos,
                    crouchCheckSize,
                    crouchCheckDirection,
                    0f,
                    priv_WhatIsCeiling
                    ))
            {
                crouch = true;
            }

            Vector2 myGravity = (priv_Grounded) ?
                                Vector2.zero :
                                ((myVelocity.y < 0) ?
                                 new Vector2(0f, playerGravity * fallMultiplier) :
                                 ((jumpHold) ?
                                  new Vector2(0f, playerGravity * holdJumpFallMultiplier) :
                                  new Vector2(0f, playerGravity * lowJumpMultiplier)));

            // Set whether or not the character is crouching in the animator
            priv_Anim.SetBool("Crouch", crouch);
            if (crouch)
            {
                SetStateCrouch = PlayerStateCrouch.Crouch;
            }
            else
            {
                SetStateCrouch = PlayerStateCrouch.No;
            }

            // Reduce the speed if crouching by the crouchSpeed multiplier
            if (stateCrouch == PlayerStateCrouch.Crouch)
            {
                move = (crouch ? move * priv_CrouchSpeed : move);
            }

            //only control the player if grounded or airControl is turned on
            if (priv_Grounded || priv_AirControl)
            {
                // The Speed animator parameter is set to the absolute value of the horizontal input.
                priv_Anim.SetFloat("Speed", Mathf.Abs(move));

                // Move the character
                if (priv_Grounded)
                {
                    myVelocity = new Vector2(
                        move * myMaxSpeed * Mathf.Cos(avgNormAngle),
                        move * myMaxSpeed * Mathf.Sin(avgNormAngle));
                    if (myVelocity.x != 0)
                    {
                        stateGrounded = PlayerStateGrounded.Run;
                    }
                    else
                    {
                        stateGrounded = PlayerStateGrounded.Idle;
                    }
                }
                else
                {
                    myVelocity = new Vector2(move * myMaxSpeed, myVelocity.y);
                    if (myVelocity.y >= 0)
                    {
                        stateAerial = PlayerStateAerial.Jump;
                    }
                    else
                    {
                        stateAerial = PlayerStateAerial.Fall;
                    }
                }

                // If the input is moving the player right and the player is facing left...
                if (move > 0 && !priv_FacingRight)
                {
                    // ... flip the player.
                    Flip();
                }
                // Otherwise if the input is moving the player left and the player is facing right...
                else if (move < 0 && priv_FacingRight)
                {
                    // ... flip the player.
                    Flip();
                }
            }

            myVelocity += myGravity * Time.deltaTime;

            // If the player should jump...
            if (jump && !crouch)
            {
                // Tell the game that a jump input is waiting
                priv_jumpInput = true;
                if (airborneFrames > airborneGracePeriod)
                {
                    Debug.Log("air jump attempt");
                }
            }
            if (priv_jumpInput && (priv_Grounded || airborneFrames <= airborneGracePeriod))
            {
                // Add a vertical force to the player.
                myWallFollow = 0f;
                Debug.Log(airborneFrames);
                priv_jumpInput   = false;
                jumpBufferFrames = 0;
                priv_Grounded    = false;
                priv_Anim.SetBool("Ground", false);
                myVelocity = new Vector2(myVelocity.x, priv_JumpSpeed);
            }

            //Whim: How we set the player's move is dependant on the physics check
            priv_Rigidbody2D.velocity = myVelocity;
            transform.position       += new Vector3(0f, -myWallFollow, 0f);
        }
Пример #3
0
        private void CollisionChecks()
        {
            //We now only set the object to grounded by collision. This works more reliably
            capsuleBottom = new Vector3(
                quickCapsule.offset.x * Mathf.Abs(transform.lossyScale.x) + transform.position.x,
                quickCapsule.offset.y * transform.lossyScale.y + transform.position.y,
                transform.position.z);                 //Whim: Forgot to remove Transform Point here. This caused the center to be far off into the distance
            Vector2 quickNormal       = Vector2.zero;
            Vector2 quickTotalNormals = Vector2.zero;
            Vector2 quickAvgNormal    = Vector2.zero;
            int     quickTotal        = 0;

            rayHits = new List <RaycastHit2D>();

            //Whim: A parameter to find the shortest distance from a wall
            myWallFollow = Mathf.Infinity;

            //Set the normals from a check flat in size
            if (priv_Grounded)
            {
                foreach (RaycastHit2D repHit in
                         Physics2D.RaycastAll(
                             (Vector2)capsuleBottom,                                                                                                                          //Origin. Place the check from the center of the character
                             Vector2.down,                                                                                                                                    //Direction, down of course
                             0.3f + Mathf.Abs(myVelocity.x * Time.deltaTime / Mathf.Tan(slipAngle * Mathf.Deg2Rad) * 3f) + quickCapsule.size.y / 2f * transform.lossyScale.y, //The distance has the speed accounted for, and the gap for when on a slope
                             Physics2D.GetLayerCollisionMask(LayerMask.NameToLayer("PlayerLayer")))                                                                           //The mask
                         )
                {
                    if (repHit.normal.y < Mathf.Cos(slipAngle * Mathf.Deg2Rad) || repHit.distance - quickCapsule.size.y / 2f * transform.lossyScale.y <= -0.1f)
                    {
                        continue;
                    }

                    quickTotalNormals += repHit.normal;
                    quickTotal++;
                }

                //Do this check to accurately see if you're standing on a platform, and to get a good value for myFollow
                foreach (RaycastHit2D repHit in
                         Physics2D.CapsuleCastAll(
                             (Vector2)capsuleBottom,                                                                                             //origin
                             new Vector2(quickCapsule.size.x * Mathf.Abs(transform.lossyScale.x), quickCapsule.size.y * transform.lossyScale.y), //size
                             quickCapsule.direction,                                                                                             //capsuleDirection
                             0f,                                                                                                                 //angle (it may be 90)
                             Vector2.down,                                                                                                       //raycast direction
                             0.2f + Mathf.Abs(myVelocity.x * Time.deltaTime / Mathf.Tan(slipAngle * Mathf.Deg2Rad) * 3f),                        //Raycast distance.
                             Physics2D.GetLayerCollisionMask(LayerMask.NameToLayer("PlayerLayer"))                                               //Collision mask
                             )
                         )
                {
                    //Debug.Log(repHit.collider.gameObject.name);
                    if (repHit.normal.y < Mathf.Cos(slipAngle * Mathf.Deg2Rad) || repHit.distance <= -0.1f)
                    {
                        continue;
                    }

                    if (repHit.distance - 0.01f < myWallFollow)
                    {
                        myWallFollow = repHit.distance - 0.01f;
                    }
                    rayHits.Add(repHit);
                }
            }
            //Debug.Log(rayHits.Count);
            if (rayHits.Count == 0)
            {
                priv_Grounded = false;
                myWallFollow  = 0f;
                avgNormAngle  = 0f;
            }
            else
            {
                priv_Grounded = true;
                stateAerial   = PlayerStateAerial.No;
                float slowDownSpeed = myOriginalMaxSpeed / 2f + (myOriginalMaxSpeed * (1f - Mathf.InverseLerp(steepAngle, slipAngle, Mathf.Abs(avgNormAngle) * Mathf.Rad2Deg)) / 2f);
                float speedUpSpeed  = myOriginalMaxSpeed + (myOriginalMaxSpeed * (Mathf.InverseLerp(speedUpAngle, slipAngle, Mathf.Abs(avgNormAngle) * Mathf.Rad2Deg)) / 3f);
                if (quickTotal > 0)
                {
                    quickAvgNormal = quickTotalNormals / (float)quickTotal;
                    avgNormAngle   = Mathf.Atan2(quickTotalNormals.y / (float)quickTotal, quickTotalNormals.x / (float)quickTotal) - Mathf.PI / 2f;
                }
                else
                {
                    myWallFollow = 0;
                }
                myWallFollow = ((myWallFollow > 0.03 && quickTotal > 0) ? myWallFollow : 0f);
                if (quickAvgNormal.y < Mathf.Cos(steepAngle * Mathf.Deg2Rad) && myVelocity.y > 0)
                {
                    myMaxSpeed = slowDownSpeed;
                }
                if (quickAvgNormal.y >= -Mathf.Cos(speedUpAngle * Mathf.Deg2Rad) && myVelocity.y < 0)
                {
                    myMaxSpeed = speedUpSpeed;
                }
            }
            Debug.Log("" + Mathf.Round(myVelocity.magnitude * 100f) / 100f + ", " + Mathf.Round(myMaxSpeed * 100f) / 100f + ", " + Mathf.Round(avgNormAngle * Mathf.Rad2Deg * 100f) / 100f + ", " + Mathf.Round(quickAvgNormal.y * 100f) / 100f);
            priv_Anim.SetBool("Ground", priv_Grounded);
            // This tracks how long the character's been in the air
            // There's a threshold for this frame counter during which the player can still jump
            // Theoretically this could allow for more than 1 jump in midair, but it's too small a timespan to be of much use anyhow
            if (!priv_Grounded)
            {
                airborneFrames++;
            }
            else
            {
                airborneFrames = 0;
            }
            // Handles the jump buffer
            // If a player presses jump right before landing, this ensures the command still goes through
            // This makes the game feel more responsive
            if (priv_jumpInput)
            {
                jumpBufferFrames++;
            }
            if (jumpBufferFrames > jumpBufferReset)
            {
                jumpBufferFrames = 0;
                priv_jumpInput   = false;
                Debug.Log("reset");
            }

            // Set the vertical animation
            priv_Anim.SetFloat("vSpeed", myVelocity.y);
        }