Files
HacknSlash/Assets/Synty/AnimationBaseLocomotion/Samples/Scripts/SyntyPlayerCombat.cs

137 lines
4.3 KiB
C#
Raw Normal View History

2026-06-18 16:37:02 +01:00
using UnityEngine;
using Synty.AnimationBaseLocomotion.Samples.InputSystem;
namespace Synty.AnimationBaseLocomotion.Samples
{
[RequireComponent(typeof(SamplePlayerAnimationController))]
public class SyntyPlayerCombat : MonoBehaviour
{
[Header("References")]
public SamplePlayerAnimationController movementController;
public Animator animator;
public InputReader inputReader;
[Header("Combat Settings")]
public float comboWindow = 1.2f;
public Transform weaponHitPoint;
public float attackRadius = 3.5f; // Big radius for Musou sweeps
public int damage = 10;
public float knockbackForce = 25f;
public LayerMask enemyLayer;
private int baseDamage;
private float baseKnockback;
private Coroutine buffCoroutine;
private float lastAttackTime;
private int comboStep = 0;
void Reset()
{
movementController = GetComponent<SamplePlayerAnimationController>();
animator = GetComponent<Animator>();
inputReader = GetComponent<InputReader>();
}
private void OnEnable()
{
if (inputReader != null)
{
inputReader.onAttackPerformed += PerformAttack;
}
}
private void OnDisable()
{
if (inputReader != null)
{
inputReader.onAttackPerformed -= PerformAttack;
}
}
void Start()
{
baseDamage = damage;
baseKnockback = knockbackForce;
}
void Update()
{
// Reset the combo step and unlock movement if the player stops pressing attack
if (comboStep > 0 && Time.time - lastAttackTime > comboWindow)
{
comboStep = 0;
movementController.IsAttacking = false;
}
// Attack input is handled via the InputReader's onAttackPerformed event
}
private void PerformAttack()
{
lastAttackTime = Time.time;
// Lock movement in the Synty controller
movementController.IsAttacking = true;
comboStep++;
if (comboStep > 3) comboStep = 1; // Loop the 3-hit combo
animator.SetTrigger("Attack" + comboStep);
}
// --- ANIMATION EVENTS ---
/// <summary>
/// Trigger this via Animation Event at the exact frame the sword connects.
/// </summary>
public void ExecuteAttackHit()
{
Collider[] hitEnemies = Physics.OverlapSphere(weaponHitPoint.position, attackRadius, enemyLayer);
foreach (Collider enemy in hitEnemies)
{
// Assumes the EnemyAI script from the Swarm architecture
EnemyAI health = enemy.GetComponentInParent<EnemyAI>();
if (health != null)
{
health.TakeDamage(damage, transform.position, knockbackForce);
}
}
}
/// <summary>
/// Trigger this via Animation Event at the very end of the attack animation clip.
/// </summary>
public void EndAttack()
{
movementController.IsAttacking = false;
}
void OnDrawGizmosSelected()
{
if (weaponHitPoint != null)
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(weaponHitPoint.position, attackRadius);
}
}
public void ApplyStrengthBuff(float multiplier, float duration)
{
// If we grab a second strength pickup while one is already active, reset the timer
if (buffCoroutine != null) StopCoroutine(buffCoroutine);
buffCoroutine = StartCoroutine(StrengthRoutine(multiplier, duration));
}
private System.Collections.IEnumerator StrengthRoutine(float multiplier, float duration)
{
Debug.Log("<color=red>Strength Buff Active!</color>");
damage = Mathf.RoundToInt(baseDamage * multiplier);
knockbackForce = baseKnockback * multiplier;
yield return new WaitForSeconds(duration);
Debug.Log("<color=white>Strength Buff Faded.</color>");
damage = baseDamage;
knockbackForce = baseKnockback;
}
}
}