using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
private float horizontal;
private float speed = 8f;
private float jumpingPower = 10f;
private bool isFacingRight = true;
private bool isWallSliding;
private float wallSlidingSpeed = 2f;
private bool isWallJumping;
private float wallJumpingDirection;
private float wallJumpingTime = 0.4f;
private float wallJumpingCounter;
private float maxWallJumpSpeed = 5f;
private Vector2 wallJumpingPower = new Vector2(5f, 9f);
private bool canWallJump = true;
private float wallJumpCooldown = 0.2f; // Duration of the cooldown period
[SerializeField] private Rigidbody2D rb; // Assign in Inspector
[SerializeField] private Transform groundCheck; // Assign in Inspector
[SerializeField] private LayerMask groundLayer; // Assign in Inspector
[SerializeField] private Transform wallCheck; // Assign in Inspector
[SerializeField] private LayerMask wallLayer; // Assign in Inspector
[SerializeField] private BoxCollider2D playerCollider; // Assign in Inspector
void Update()
{
horizontal = Input.GetAxisRaw("Horizontal");
if (Input.GetButtonDown("Jump") && IsGrounded())
{
rb.linearVelocity = new Vector2(rb.linearVelocity.x, jumpingPower);
}
if (Input.GetButtonUp("Jump") && rb.linearVelocity.y > 0f)
{
rb.linearVelocity = new Vector2(rb.linearVelocity.x, rb.linearVelocity.y * 0.5f);
}
// Slide input has been moved to a separate script
wallSlide();
wallJump();
if (!isWallJumping)
{
Flip();
}
}
private bool IsGrounded()
{
return Physics2D.OverlapCircle(groundCheck.position, 0.3f, groundLayer);
}
private void FixedUpdate()
{
// Get a reference to the PlayerSlide script (e.g., via GetComponent)
PlayerSlide slideScript = GetComponent<PlayerSlide>();
if (!isWallJumping)
{
rb.linearVelocity = new Vector2(horizontal * speed, rb.linearVelocity.y);
}
}
private bool isWalled()
{
return Physics2D.OverlapCircle(wallCheck.position, 0.2f, wallLayer);
}
private void wallSlide()
{
if (isWalled() && !IsGrounded() && horizontal != 0f)
{
isWallSliding = true;
rb.linearVelocity = new Vector2(rb.linearVelocity.x, Mathf.Clamp(rb.linearVelocity.y, -wallSlidingSpeed, float.MaxValue));
}
else
{
isWallSliding = false;
}
}
private void wallJump()
{
if (isWallSliding && canWallJump)
{
isWallJumping = false;
wallJumpingDirection = -transform.localScale.x;
wallJumpingCounter = wallJumpingTime;
CancelInvoke(nameof(stopWallJumping));
}
else
{
wallJumpingCounter -= Time.deltaTime;
}
if (Input.GetButtonDown("Jump") && wallJumpingCounter > 0f && canWallJump)
{
isWallJumping = true;
rb.linearVelocity = new Vector2(wallJumpingDirection * wallJumpingPower.x, wallJumpingPower.y);
wallJumpingCounter = 0f;
if (transform.localScale.x != wallJumpingDirection)
{
isFacingRight = !isFacingRight;
Vector3 localScale = transform.localScale;
localScale.x *= -1f;
transform.localScale = localScale;
}
float clampedX = Mathf.Clamp(rb.linearVelocity.x, -maxWallJumpSpeed, maxWallJumpSpeed);
rb.linearVelocity = new Vector2(clampedX, rb.linearVelocity.y);
canWallJump = false;
Invoke(nameof(ResetWallJump), wallJumpCooldown);
Invoke(nameof(stopWallJumping), wallJumpingTime);
}
}
private void ResetWallJump()
{
canWallJump = true;
}
private void stopWallJumping()
{
isWallJumping = false;
}
private void Flip()
{
if ((isFacingRight && horizontal < 0) || (!isFacingRight && horizontal > 0))
{
isFacingRight = !isFacingRight;
Vector3 localScale = transform.localScale;
localScale.x *= -1f;
transform.localScale = localScale;
}
}
}