예제 #1
0
        /// <summary>pretends to hold the jump button for the specified duration</summary>
        public void FixedUpdate(CharacterMove p)
        {
            if (inputHeld = (PressJump > 0))
            {
                PressJump -= Time.deltaTime;
            }
            if (impulseActive && !inputHeld)
            {
                impulseActive = false;
            }
            if (!inputHeld)
            {
                return;
            }
            bool isStableOnGround = p.IsStableOnGround();

            // check stable footing for the jump
            if (isStableOnGround)
            {
                jumpsSoFar          = 0;
                heightReached       = 0;
                currentJumpVelocity = 0;
                timeHeld            = 0;
            }
            // calculate the jump
            float   gForce = -Physics.gravity.y * p.rb.mass;
            Vector3 jump_force = Vector3.zero, jumpDirection = Vector3.up;//-p.gravity.dir;

            // if the user wants to jump, and is allowed to jump again
            if (!impulseActive && (jumpsSoFar < maxJumps))
            {
                heightReached = 0;
                timeHeld      = 0;
                jumpsSoFar++;
                targetHeight = minJumpHeight * p.rb.mass;
                float velocityRequiredToJump = Mathf.Sqrt(targetHeight * 2 * gForce);
                // cancel out current jump/fall forces
                if (jumpStartResetsVerticalMotion)
                {
                    float motionInVerticalDirection = Vector3.Dot(jumpDirection, p.rb.velocity);
                    jump_force -= (motionInVerticalDirection * jumpDirection) / Time.deltaTime;
                }
                // apply proper jump force
                currentJumpVelocity = velocityRequiredToJump;
                peaked        = false;
                jump_force   += (jumpDirection * currentJumpVelocity) / Time.deltaTime;
                impulseActive = true;
            }
            else
            // if a jump is happening
            if (currentJumpVelocity > 0)
            {
                // handle jump height: the longer you hold jump, the higher you jump
                if (inputHeld)
                {
                    timeHeld += Time.deltaTime;
                    if (timeHeld >= fullJumpPressDuration)
                    {
                        targetHeight = maxJumpHeight;
                        timeHeld     = fullJumpPressDuration;
                    }
                    else
                    {
                        targetHeight  = minJumpHeight + ((maxJumpHeight - minJumpHeight) * timeHeld / fullJumpPressDuration);
                        targetHeight *= p.rb.mass;
                    }
                    if (heightReached < targetHeight)
                    {
                        float requiredJumpVelocity = Mathf.Sqrt((targetHeight - heightReached) * 2 * gForce);
                        float forceNeeded          = requiredJumpVelocity - currentJumpVelocity;
                        jump_force         += (jumpDirection * forceNeeded) / Time.deltaTime;
                        currentJumpVelocity = requiredJumpVelocity;
                    }
                }
            }
            else
            {
                impulseActive = false;
            }
            if (currentJumpVelocity > 0)
            {
                float moved = currentJumpVelocity * Time.deltaTime;
                heightReached       += moved;
                heightReachedTotal  += moved;
                currentJumpVelocity -= gForce * Time.deltaTime;
            }
            else if (!peaked && !isStableOnGround)
            {
                peaked        = true;
                impulseActive = false;
            }
            p.rb.AddForce(jump_force);
        }