Example #1
0
    private void Awake()
    {
        UpdateKinematics();
        collisionController = GetComponent <CollisionController>();
        dialogueManager     = GetComponent <DialogueManager>();

        // Quick hack, need this initialized on the first frame.
        collisionInfo           = new CollisionController.CollisionInfo();
        collisionInfo.colliders = new Dictionary <Vector3, Collider>();
        soundController         = GetComponent <SoundController>();
    }
Example #2
0
    private void TriggerSolidCollidables()
    {
        // Get solid collidables from player movement and collisions.
        collInfo = playerMovement.GetCollisionInfo();

        foreach (KeyValuePair <Vector3, Collider> pair in collInfo.colliders)
        {
            if (!collidableMap.ContainsKey(pair.Value))
            {
                continue;
            }

            // Send collided signal. NB: the collision direction is inverted since the perspective changes to the other object.
            collidableMap[pair.Value].Collided(pair.Key * -1);
        }
    }
Example #3
0
    private void Update()
    {
        if (isRetrieving)
        {
            return;
        }

        child.Rotate(Vector3.forward * rotationSpeed * Time.deltaTime);

        // Calculate new velocity
        velocity.y = Mathf.Clamp(velocity.y + gravity * Time.deltaTime, -terminalVelocity, terminalVelocity);

        // Calculate new position and check for collisions.
        collisionInfo = collisionController.Check(velocity * Time.deltaTime);

        // Move to new position.
        transform.Translate(collisionInfo.moveVector);

        // React to collisions.
        if (collisionInfo.colliderHorizontal != null || collisionInfo.colliderVertical != null)
        {
            this.enabled = false;
        }
    }
    public void Update()
    {
        if (coyoteTimeEnabled)
        {
            coyoteTimeLeft -= Time.deltaTime;
            // Get rid of primary jump if no coyote time is left.
            if (jumpsLeft == jumps && coyoteTimeLeft <= 0)
            {
                jumpsLeft--;
            }
        }
        else
        {
            // Get rid of primary jump if not on the ground.
            if (jumpsLeft == jumps && !collisionInfo.collisionBelow)
            {
                jumpsLeft--;
            }
        }

        // Register jump input ahead of time for buffer and use it if applicable, keep track of time since jump input.
        if (jumpBufferTimeLeft >= 0)
        {
            jumpBufferTimeLeft -= Time.deltaTime;
        }
        if (Input.GetKeyDown(KeyCode.Space))
        {
            jumpBufferTimeLeft = jumpBufferTime;
        }

        // Calculate horizontal movement.
        float hInput = Input.GetAxisRaw("Horizontal");

        // If we are sticking to wall, there's no horizontal movement to calculate.
        if (!(wallJumpingEnabled && wallStickingInfo.IsSticking()))
        {
            isRunning = true;
            if (walkingEnabled)
            {
                isRunning = Input.GetKey(KeyCode.LeftShift);
            }
            float targetSpeed = hInput * (isRunning ? runSpeed : walkSpeed);
            velocity.x = (velocity.x > targetSpeed) ? Mathf.Max(targetSpeed, velocity.x - (acceleration * Time.deltaTime))
                                                    : Mathf.Min(velocity.x + (acceleration * Time.deltaTime), targetSpeed);
        }

        // Special case: Wall jumping requires precise tricky timing of inputs.
        // Give the player a little bit of time to correct their mistake.
        if (toLaunchGracePeriodLeft > 0 && hInput == -wallDirection)
        {
            velocity.x = -wallDirection *Mathf.Cos(wallJumpLaunchAngle *Mathf.Deg2Rad);

            velocity.y = Mathf.Sin(wallJumpLaunchAngle * Mathf.Deg2Rad);
            velocity  *= wallJumpLaunchSpeed;
            toLaunchGracePeriodLeft = -1;
        }

        // Calculate vertical movement. (By gravity or by jumping.)
        if (wallJumpingEnabled && toLaunchGracePeriodLeft > 0)
        {
            toLaunchGracePeriodLeft -= Time.deltaTime;
        }
        velocity.y = Mathf.Clamp(velocity.y + gravity * Time.deltaTime, -terminalVelocity, terminalVelocity);
        if (jumpBufferTimeLeft >= 0)
        {
            if (wallJumpingEnabled && wallStickingInfo.IsSticking())
            {
                // Wall jump
                wallDirection = wallStickingInfo.GetWallDirection();
                if (hInput == wallDirection)
                {
                    velocity.x = -wallDirection *Mathf.Cos(wallJumpClimbAngle *Mathf.Deg2Rad);

                    velocity.y = Mathf.Sin(wallJumpClimbAngle * Mathf.Deg2Rad);
                    velocity  *= wallJumpClimbSpeed;
                    // Set launching grace period.
                    toLaunchGracePeriodLeft = toLaunchGracePeriod;
                }
                else if (hInput == 0)
                {
                    velocity.x = -wallDirection *Mathf.Cos(wallJumpHopAngle *Mathf.Deg2Rad);

                    velocity.y = Mathf.Sin(wallJumpHopAngle * Mathf.Deg2Rad);
                    velocity  *= wallJumpHopSpeed;
                    // Set launching grace period.
                    toLaunchGracePeriodLeft = toLaunchGracePeriod;
                }
                else
                {
                    velocity.x = -wallDirection *Mathf.Cos(wallJumpLaunchAngle *Mathf.Deg2Rad);

                    velocity.y = Mathf.Sin(wallJumpLaunchAngle * Mathf.Deg2Rad);
                    velocity  *= wallJumpLaunchSpeed;
                }
                jumpBufferTimeLeft = -1;
                wallStickingInfo.Reset();
            }
            else if (jumpsLeft > 0)
            {
                // Regular jumps
                velocity.y = (jumps == jumpsLeft ? maxJumpVelocity : maxMultiJumpVelocity);
                jumpsLeft--;
                // Just set the jump timer to negative to "consume" input.
                jumpBufferTimeLeft = -1;
                soundController.playJumpSound();
            }
        }

        // Shortening jumps by releasing space.
        if (VariableJumpEnabled && Input.GetKeyUp(KeyCode.Space))
        {
            if (jumps == jumpsLeft + 1)
            {
                if (velocity.y > minJumpVelocity)
                {
                    velocity.y = minJumpVelocity;
                }
            }
            else
            {
                if (velocity.y > minMultiJumpVelocity)
                {
                    velocity.y = minMultiJumpVelocity;
                }
            }
        }

        // Calculate change in position based on collisions.
        collisionInfo = collisionController.Check(velocity * Time.deltaTime);

        // React to vertical collisions.
        if (collisionInfo.colliderVertical != null)
        {
            velocity.y = 0;
            // If collision is below, reset jumping and coyote time (if enabled).
            if (collisionInfo.collisionBelow)
            {
                if (coyoteTimeEnabled)
                {
                    coyoteTimeLeft = coyoteTime;
                }
                if (wallJumpingEnabled)
                {
                    // Remove wall sticking if grounded.
                    wallStickingInfo.Reset();
                }
                jumpsLeft = jumps;
            }
        }

        // React to horizontal collisions.
        if (collisionInfo.colliderHorizontal != null)
        {
            velocity.x = 0;
        }

        if (wallJumpingEnabled)
        {
            wallStickingInfo.Tick();
        }
        bool pushingAgainstWall = !collisionInfo.collisionBelow && ((collisionInfo.collisionRight && hInput == 1) || (collisionInfo.collisionLeft && hInput == -1));

        // If we are pushing against a wall without any ground, reset stick.
        if (wallJumpingEnabled && pushingAgainstWall)
        {
            wallStickingInfo.Reset(collisionInfo.collisionRight ? 1 : -1, wallStickTime);
        }
        // If we are pushing against a wall or stuck to it, slide.
        if ((wallJumpingEnabled && wallStickingInfo.IsSticking()) || pushingAgainstWall)
        {
            // Sliding
            if (wallSlideEnabled && velocity.y < wallSlideSpeed)
            {
                velocity.y = -wallSlideSpeed;
            }
        }

        // Special case: If we are sticking but we aren't against a wall, stop sticking. (Usually happens when sliding off a wall.)
        if (wallJumpingEnabled && wallStickingInfo.IsSticking())
        {
            if (!collisionController.Check(Vector2.right * 0.01f).collisionRight&& !collisionController.Check(Vector2.left * 0.01f).collisionLeft)
            {
                wallStickingInfo.Reset();
            }
        }

        // Move the object.
        transform.Translate(collisionInfo.moveVector);
    }
Example #5
0
    private void Update()
    {
        if (coyoteTimeEnabled)
        {
            coyoteTimeLeft -= Time.deltaTime;
            // Get rid of primary jump if no coyote time is left.
            if (jumpsLeft == jumps && coyoteTimeLeft <= 0)
            {
                jumpsLeft--;
            }
        }
        else
        {
            // Get rid of primary jump if not on the ground.
            if (jumpsLeft == jumps && !collisionInfo.colliders.ContainsKey(Vector3.down))
            {
                jumpsLeft--;
            }
        }

        // Register jump input ahead of time for buffer and use it if applicable, keep track of time since jump input.
        if (jumpBufferTimeLeft >= 0)
        {
            jumpBufferTimeLeft -= Time.deltaTime;
        }
        // Only do jumps if we are not in dialogue.
        if (Input.GetKeyDown(KeyCode.Space) && !dialogueManager.isOpen)
        {
            jumpBufferTimeLeft = jumpBufferTime;
        }

        // Calculate horizontal movement.

        /*TODO (possibly): hInput is not normalized. Meaning you cover more ground if you are traveling diagonally.
         * Mathematically, that is wrong: your top speed shouldn't increase if your heading changes. However,
         * in the game it FEELS better if you have acceleration. Which means I have to side with game feel. And it
         * bothers me so much. I don't know if I am doing something wrong with the numbers that I haven't noticed.
         * It's possible that because the player doesn't face the exact direction it is heading (it can only face the
         * four cardinal directions), when the player doesn't visually rotate but slows down in one axis when it is
         * normalized. Leading to bad game feel. I don't know.*/
        Vector3 hInput = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical")) /*.normalized*/;

        // Cancel out hInput if we have dialogue open.
        if (dialogueManager.isOpen)
        {
            hInput = Vector3.zero;
        }
        velocity.x = (velocity.x > hInput.x * runSpeed) ? Mathf.Max(hInput.x * runSpeed, velocity.x - (acceleration * Time.deltaTime))
                                                        : Mathf.Min(velocity.x + (acceleration * Time.deltaTime), hInput.x * runSpeed);
        velocity.z = (velocity.z > hInput.z * runSpeed) ? Mathf.Max(hInput.z * runSpeed, velocity.z - (acceleration * Time.deltaTime))
                                                        : Mathf.Min(velocity.z + (acceleration * Time.deltaTime), hInput.z * runSpeed);

        // Always apply gravity.
        velocity.y = Mathf.Clamp(velocity.y + gravity * Time.deltaTime, -terminalVelocity, terminalVelocity);

        // Calculate vertical movement.
        if (jumpBufferTimeLeft >= 0 && jumpsLeft > 0)
        {
            velocity.y = (jumps == jumpsLeft ? maxJumpVelocity : maxMultiJumpVelocity);
            jumpsLeft--;
            soundController.PlayJumpSound();
            // Just set the jump timer to negative to "consume" input.
            jumpBufferTimeLeft = -1;
            if (variableJumpEnabled)
            {
                variableJumpActive = true;
            }
        }

        // Shortening jumps by releasing space.
        if (variableJumpEnabled && Input.GetKeyUp(KeyCode.Space) && variableJumpActive)
        {
            variableJumpActive = false;
            if (jumps == jumpsLeft + 1)
            {
                if (velocity.y > minJumpVelocity)
                {
                    velocity.y = minJumpVelocity;
                }
            }
            else
            {
                if (velocity.y > minMultiJumpVelocity)
                {
                    velocity.y = minMultiJumpVelocity;
                }
            }
        }

        // Do the collision check.
        collisionInfo = collisionController.Check(velocity * Time.deltaTime);

        // If the ground is below us, stop.
        if (collisionInfo.colliders.ContainsKey(Vector3.down) || collisionInfo.colliders.ContainsKey(Vector3.up))
        {
            velocity.y = 0;
            // If collision is below, reset jumping and coyote time (if enabled).
            if (collisionInfo.colliders.ContainsKey(Vector3.down))
            {
                if (coyoteTimeEnabled)
                {
                    coyoteTimeLeft = coyoteTime;
                }
                jumpsLeft            = jumps;
                lastGroundedPosition = transform.position;
            }
        }

        // React to horizontal collisions.
        if (collisionInfo.colliders.ContainsKey(Vector3.right) || collisionInfo.colliders.ContainsKey(Vector3.left))
        {
            velocity.x = 0;
        }
        if (collisionInfo.colliders.ContainsKey(Vector3.forward) || collisionInfo.colliders.ContainsKey(Vector3.back))
        {
            velocity.z = 0;
        }

        // Move the player.
        transform.Translate(collisionInfo.moveVector);
    }