I am trying to implement a parry system for my 2d game. When the player runs to the right and then tries to parry, the parry either works one time and then fails or fails from the start. If the player runs to the left and then tries to parry, the parry works every time. It can be fixed or broken during runtime by running to the left or right respectively. Facing direction does not matter. Any help is appreciated. Thank you in advance.
using UnityEngine;
public enum ParryType
{
None,
Horizontal,
Vertical
}
public class PlayerParry : MonoBehaviour
{
public float parryWindow = 0.2f; // The time window in seconds to perform a successful parry
private float parryCooldown = 0.5f; // Cooldown between parries
private bool canParry = true; // To track if the player can attempt a parry
private bool isInParryWindow = false; // To check if within parry timing
private float parryTimer = 0f; // Tracks time within parry window
private float cooldownTimer = 0f; // Tracks cooldown time
private PostureSystem posture;
public int postureIncreaseAmount = 10;
private Animator anim;
private bool parrying = false;
private ParryType currentParryType = ParryType.None; // Tracks the current parry type
private void Awake()
{
anim = GetComponentInParent<Animator>();
posture = GetComponentInParent<PostureSystem>();
}
private void Update()
{
HandleParryInput();
ManageParryTimers();
}
private void HandleParryInput()
{
// Check for horizontal parry input
if (Input.GetKeyDown(KeyCode.Q) && canParry && currentParryType == ParryType.None)
{
StartParry(ParryType.Horizontal);
}
// Check for vertical parry input
if (Input.GetKeyDown(KeyCode.E) && canParry && currentParryType == ParryType.None)
{
StartParry(ParryType.Vertical);
}
}
// Method to initiate the parry attempt and set timers
private void StartParry(ParryType parryType)
{
anim.SetTrigger("ParryStance");
isInParryWindow = true;
parryTimer = 0f;
canParry = false;
currentParryType = parryType; // Set the current parry type
}
private void ManageParryTimers()
{
if (isInParryWindow)
{
parryTimer += Time.deltaTime;
if (parryTimer > parryWindow)
{
isInParryWindow = false;
// Keep the parry type active for this frame to ensure late collision checks work
Invoke("ResetParryType", 0.1f);
}
}
if (!canParry)
{
cooldownTimer += Time.deltaTime;
if (cooldownTimer > parryCooldown)
{
canParry = true;
cooldownTimer = 0f;
}
}
}
private void ResetParryType()
{
currentParryType = ParryType.None;
}
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.CompareTag("HorizontalAttack") || collision.CompareTag("VerticalAttack") && !parrying)
{
HandleParryCollision(collision);
}
}
private void OnTriggerStay2D(Collider2D collision)
{
if (collision.CompareTag("HorizontalAttack") || collision.CompareTag("VerticalAttack") && !parrying)
{
HandleParryCollision(collision);
}
}
private void HandleParryCollision(Collider2D collision)
{
Debug.Log("Try to Parry");
if (isInParryWindow)
{
if (collision.CompareTag("HorizontalAttack") && currentParryType == ParryType.Horizontal)
{
SuccessfulParry(collision);
}
else if (collision.CompareTag("VerticalAttack") && currentParryType == ParryType.Vertical)
{
SuccessfulParry(collision);
}
else
{
posture.IncreasePosture(postureIncreaseAmount);
WrongParryFeedback();
}
}
else if (collision.CompareTag("HorizontalAttack") || collision.CompareTag("VerticalAttack"))
{
Debug.Log("Attack Hit Player!");
parrying = false;
}
}
private void WrongParryFeedback()
{
Debug.Log("Incorrect parry type used!");
// Add effects here
}
private void SuccessfulParry(Collider2D collision)
{
isInParryWindow = false; // End the parry window
currentParryType = ParryType.None; // Reset parry type
Debug.Log("Parry Successful!");
anim.SetTrigger("Parry");
collision.GetComponentInParent<PostureSystem>().IncreasePosture(postureIncreaseAmount);
parrying = false;
// Add additional parry feedback (e.g., effects, sound) here
}
}