Player movement

 avatar
unknown
csharp
a year ago
10 kB
8
Indexable
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    private float horizontal;
    private float vertical;
    [SerializeField] private float speed = 8f;
    [SerializeField] private float jumpingPower = 16f;
    private bool isFacingRight = true;
    public SlowDownTime slowDownTime;

    private bool isJumping;
    private bool canDoubleJump;

    private float coyoteTime = 0.2f;
    private float coyoteTimeCounter;

    private float jumpBufferTime = 0.2f;
    private float jumpBufferCounter;

    [SerializeField] private Rigidbody2D rb;
    [SerializeField] private Transform groundCheck;
    [SerializeField] private LayerMask groundLayer;
    [SerializeField] private TrailRenderer trail;

    [SerializeField] private bool enableDoubleJump = true; // New variable to enable/disable double jump

    [Header("---Wall Climbing---")]
    [SerializeField] private float wallSlidingSpeed = 2f;
    [SerializeField] private Transform wallCheck;
    [SerializeField] private LayerMask wallLayer;
    [SerializeField] private float wallClimbingSpeed;
    [SerializeField] private float maxWallTime = 5;
    private float wallTime;
    private bool isWallSliding;

    [Header("---Wall Jumping---")]
    [SerializeField] private float wallJumpingPowerX;
    [SerializeField] private float wallJumpingPowerY;
    private bool isWallJumping;
    private float wallJumpingDirection;
    private float wallJumpingTime = 0.2f;
    private float wallJumpingCounter;
    private float wallJumpingDuration = 0.4f;
    private Vector2 wallJumpingPower;


    [Header("---Dash---")]
    [SerializeField] private float dashingPower = 24f;
    [SerializeField] private float verticalDashingPower = 24f;
    [SerializeField] private float diagonalDashingPower = 24f;
    [SerializeField] private float dashingTime = 0.2f;
    [SerializeField] private float dashingCooldown = 1f;
    private bool canDash = true;
    private bool isDashing;
    private bool dashOnCoolDown = false;



    //private int wallJumpCount;
    //[SerializeField] private int maxWallJumps = 2; // Maximum number of wall jumps allowed

    private float gravityScale;

    private void Start()
    {
        gravityScale = rb.gravityScale;
        wallTime = maxWallTime;
        
    }

    private void Update()
    {
        if (isDashing)
        {
            return;
        }

        wallJumpingPower = new Vector2(wallJumpingPowerX, wallJumpingPowerY);

        horizontal = Input.GetAxisRaw("Horizontal");
        vertical = Input.GetAxisRaw("Vertical");

        if (IsGrounded())
        {
            wallTime = maxWallTime;
            coyoteTimeCounter = coyoteTime;
            canDoubleJump = true; // Reset double jump when grounded
            //wallJumpCount = maxWallJumps; // Reset wall jump count when grounded
        }
        else
        {
            coyoteTimeCounter -= Time.deltaTime;
        }

        if (Input.GetButtonDown("Jump"))
        {
            jumpBufferCounter = jumpBufferTime;
        }
        else
        {
            jumpBufferCounter -= Time.deltaTime;
        }

        if (coyoteTimeCounter > 0f && jumpBufferCounter > 0f && !isJumping)
        {
            rb.velocity = new Vector2(rb.velocity.x, jumpingPower);
            jumpBufferCounter = 0f;
            StartCoroutine(JumpCooldown());
        }
        else if (enableDoubleJump && canDoubleJump && jumpBufferCounter > 0f && !isJumping)
        {
            rb.velocity = new Vector2(rb.velocity.x, jumpingPower);
            jumpBufferCounter = 0f;
            canDoubleJump = false; // Disable further double jumps
            StartCoroutine(JumpCooldown());
        }
        /*
        else if (isWallSliding && wallJumpCount > 0 && Input.GetButtonDown("Jump"))
        {
            rb.velocity = new Vector2(rb.velocity.x, jumpingPower);
            wallJumpCount--; // Decrement wall jump count
            StartCoroutine(JumpCooldown());
        }
        */

        if (Input.GetButtonUp("Jump") && rb.velocity.y > 0f)
        {
            rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y * 0.5f);
            coyoteTimeCounter = 0f;
        }

        wallSlide();
        wallJump();
        wallClimb();

        if(!isWallJumping)
        {
            Flip();
        }

        // Dashing
        if (Input.GetButtonDown("Dash") && canDash)
        {
            StartCoroutine(Teleport());
        }

        if (IsGrounded() && !dashOnCoolDown)
        {
            canDash = true;
        }
    }

    private void FixedUpdate()
    {
        if (isDashing)
        {
            return;
        }
        if (!isWallJumping && !slowDownTime._isTimeStopped)
        {
            rb.velocity = new Vector2(horizontal * speed, rb.velocity.y);
        }
        else if(slowDownTime._isTimeStopped)
        {
            rb.velocity = new Vector2(horizontal * speed * Time.unscaledDeltaTime, rb.velocity.y * Time.unscaledDeltaTime);
        }

        
    }

    private bool IsGrounded()
    {
        return Physics2D.OverlapCircle(groundCheck.position, 0.2f, groundLayer);
    }

    private void Flip()
    {
        if (isFacingRight && horizontal < 0f || !isFacingRight && horizontal > 0f)
        {
            Vector3 localScale = transform.localScale;
            isFacingRight = !isFacingRight;
            localScale.x *= -1f;
            transform.localScale = localScale;
        }
    }

    private IEnumerator JumpCooldown()
    {
        isJumping = true;
        yield return new WaitForSeconds(0.4f);
        isJumping = false;
    }

    private IEnumerator Teleport()
    {
        canDash = false;
        isDashing = true;
        float originalGravity = rb.gravityScale;
        rb.gravityScale = 0f;
        trail.emitting = true;

        Vector2 dashDirection = new Vector2(horizontal, vertical).normalized;
        if (dashDirection == Vector2.zero) // If no directional input, default to horizontal dash
        {
            dashDirection = new Vector2(transform.localScale.x, 0f);
        }

        if (dashDirection.magnitude != 0)
        {
            dashDirection.Normalize();
        }

        // Checking the dash direction
        if (dashDirection.y > 0.5f && Mathf.Abs(dashDirection.x) < 0.5f)
        {
            // Upward dash
            rb.velocity = dashDirection * verticalDashingPower;
        }
        else if (dashDirection.y < -0.5f && Mathf.Abs(dashDirection.x) < 0.5f)
        {
            // Downward dash
            rb.velocity = dashDirection * -verticalDashingPower;
        }
        else if (Mathf.Abs(dashDirection.x) > 0.5f && Mathf.Abs(dashDirection.y) < 0.5f)
        {
            // Horizontal dash
            rb.velocity = dashDirection * dashingPower;
        }
        else
        {
            // Diagonal dash
            rb.velocity = dashDirection * diagonalDashingPower;
        }

        yield return new WaitForSeconds(dashingTime);

        trail.emitting = false;
        rb.gravityScale = originalGravity;
        isDashing = false;
        dashOnCoolDown = true;

        yield return new WaitForSeconds(dashingCooldown);

        dashOnCoolDown = false;
    }

    private bool IsWalled()
    {
        return Physics2D.OverlapCircle(wallCheck.position, 0.2f, wallLayer);
    }

    
    private void wallSlide()
    {
        if (IsWalled() && !IsGrounded() && horizontal != 0f)
        {
            isWallSliding = true;
            rb.velocity = new Vector2(rb.velocity.x, Mathf.Clamp(rb.velocity.y, -wallSlidingSpeed, float.MaxValue));
        }
        else
        {
            isWallSliding = false;
        }
    }
    

    private void wallClimb()
    {
        // Store the initial velocity and gravity scale of the Rigidbody2D
        Vector2 initialVelocity = rb.velocity;
        //float initialGravityScale = rb.gravityScale;

        // Check if the "J" key is pressed and the object is colliding with a wall
        if (Input.GetKey(KeyCode.J) && IsWalled() && wallTime > 0)
        {
            // Stop the object's movement and disable gravity
            rb.velocity = Vector2.zero;
            rb.gravityScale = 0;

            wallTime -= Time.deltaTime;

            if(Input.GetButton("Up"))
            {
                rb.velocity = new Vector2(0f, wallClimbingSpeed);
                Debug.Log("Climbing up");
            }
            else if (Input.GetButton("Down"))
            {
                rb.velocity = new Vector2(0f, -wallClimbingSpeed);
                Debug.Log("Climbing down");
            }
        }
        else
        {
            // Restore the object's initial velocity and gravity scale
            //Debug.Log("Left wall");
            rb.velocity = initialVelocity;
            rb.gravityScale = gravityScale;
            
        }
    }

    private void wallJump()
    {
        if(isWallSliding)
        {
            isWallJumping = false;
            wallJumpingDirection = -transform.localScale.x;
            wallJumpingCounter = wallJumpingTime;

            CancelInvoke(nameof(stopWallJumping));
        }
        else
        {
            wallJumpingCounter -= Time.deltaTime;
        }

        if(Input.GetButtonDown("Jump") && wallJumpingCounter > 0f)
        {
            isWallJumping = true;
            rb.velocity = new Vector2(wallJumpingDirection * wallJumpingPower.x, wallJumpingPower.y);
            wallJumpingCounter = 0;

            if(transform.localScale.x != wallJumpingDirection)
            {
                isFacingRight = !isFacingRight;
                Vector3 localScale = transform.localScale;
                localScale.x *= -1f;
                transform.localScale = localScale;
            }
        }

        Invoke(nameof(stopWallJumping), wallJumpingDuration);
    }

    private void stopWallJumping()
    {
        isWallJumping = false;
    }

}
Editor is loading...
Leave a Comment