using UnityEngine;
using System.Collections;
public class Player_controller : MonoBehaviour
{
private Rigidbody2D rb;
private float xAxis;
Animator anim;
public static Player_controller Instance;
PlayerStateList pState;
private float gravity;
// --- Paramètre de la taille du personnage ---
[Header("Scale Setting")]
[SerializeField] private float xScale = 4;
// --- Paramètre de mouvement horizontaux ---
[Header("Horizontal Movement Setting")]
[SerializeField] private float walkSpeed = 1;
[Header("Dash Setting")]
[SerializeField] private float dashSpeed;
[SerializeField] private float dashTime;
[SerializeField] private float dashCooldown;
private bool canDash = true;
private bool dashed;
// --- Paramètre de saut ---
[Header("Vertical Movement Setting")]
[SerializeField] private float jumpForce = 45;
private int jumpBufferCounter = 0;
[SerializeField] private int jumpBufferFrame;
private float coyoteTimeCounter = 0;
[SerializeField] private float CoyoteTime;
private int airJumpCounter = 0;
[SerializeField] private int MaxAirJumps;
// --- Paramètre du détecteur du sol ---
[Header("GroundCheck Setting")]
[SerializeField] private Transform GroundCheckPoint;
[SerializeField] private float groundCheckY = 0.2f;
[SerializeField] private float groundCheckX = 0.5f;
[SerializeField] private LayerMask WhatIsGround;
// --- Permet le bon fonctionnement de la camèra ---
// --- (Supprime le joueur en double) ---
private void Awake()
{
if(Instance != null && Instance != this)
{
Destroy(gameObject);
}
else
{
Instance = this;
}
}
// --- Mise en place des lien entre les composant unity et le programme ---
void Start()
{
rb = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
pState = GetComponent<PlayerStateList>();
gravity = rb.gravityScale;
}
// --- Activation en boucle des fonctions ---
void Update()
{
GetInputs();
UpdateJumpVariables();
if (pState.Dashing) return;
Flip();
Move();
Jump();
StartDash();
}
// --- Récupérations des Inputs ---
void GetInputs()
{
xAxis = Input.GetAxisRaw("Horizontal");
}
// --- Permet de faire tourner le sprite en fonction de la direction ---
void Flip()
{
if(xAxis < 0)
{
transform.localScale = new Vector2(-xScale, transform.localScale.y);
}
else if(xAxis > 0)
{
transform.localScale = new Vector2(xScale, transform.localScale.y);
}
}
// --- Fonctionnement du mouvement horizontal ---
private void Move()
{
rb.linearVelocity = new Vector2(walkSpeed * xAxis, rb.linearVelocity.y);
anim.SetBool("Walking", rb.linearVelocity.x != 0 && Grounded());
}
// --- Détection du sol ---
public bool Grounded()
{
if (Physics2D.Raycast(GroundCheckPoint.position, Vector2.down, groundCheckY, WhatIsGround)
|| Physics2D.Raycast(GroundCheckPoint.position + new Vector3(groundCheckX, 0, 0) , Vector2.down, groundCheckY, WhatIsGround)
|| Physics2D.Raycast(GroundCheckPoint.position + new Vector3(-groundCheckX, 0, 0) , Vector2.down, groundCheckY, WhatIsGround))
{
return true;
}
else
{
return false;
}
}
//--------------------------------------------------------------------
// --- Fonctionnement du saut ---
//--------------------------------------------------------------------
void Jump()
{
// --- Saut de base ---
if(Input.GetButtonUp("Jump") && rb.linearVelocity.y > 0)
{
rb.linearVelocity = new Vector2(rb.linearVelocity.x, 0);
pState.Jumping = false;
}
if (!pState.Jumping)
{
if (jumpBufferCounter > 0 && coyoteTimeCounter > 0)
{
rb.linearVelocity = new Vector3(rb.linearVelocity.x, jumpForce);
pState.Jumping = true;
}
// --- ajoute le double saut ---
else if(!Grounded() && airJumpCounter < MaxAirJumps && Input.GetButtonDown("Jump"))
{
rb.linearVelocity = new Vector3(rb.linearVelocity.x, jumpForce);
pState.Jumping = true;
airJumpCounter ++;
}
}
anim.SetBool("Jumping", !Grounded());
}
// --- ajoute un temps pendant lequel l'input de saut est sauvegardé ---
// --- ajoute le coyote Time ---
void UpdateJumpVariables()
{
if (Grounded())
{
pState.Jumping = false;
coyoteTimeCounter = CoyoteTime;
airJumpCounter = 0;
}
else
{
coyoteTimeCounter -= Time.deltaTime;
}
if (Input.GetButtonDown("Jump"))
{
jumpBufferCounter = jumpBufferFrame;
}
else
{
jumpBufferCounter --;
}
}
//--------------------------------------------------------------------
// --- Fonctionnement du dash ---
//--------------------------------------------------------------------
void StartDash()
{
if(Input.GetButtonDown("DASH") && canDash && !dashed)
{
StartCoroutine(Dash());
dashed = true;
}
if (Grounded())
{
dashed = false;
}
}
IEnumerator Dash()
{
canDash = false;
pState.Dashing = true;
anim.SetTrigger("Dashing");
rb.gravityScale = 0;
rb.linearVelocity = new Vector2(transform.localScale.x * dashSpeed, 0);
yield return new WaitForSeconds(dashTime);
rb.gravityScale = gravity;
pState.Dashing = false;
yield return new WaitForSeconds(dashCooldown);
canDash = true;
}
}