137 lines
4.3 KiB
C#
137 lines
4.3 KiB
C#
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;
|
|
}
|
|
}
|
|
} |