using System; using System.Collections; using System.Collections.Generic; using Unity.Mathematics; using Unity.VisualScripting; using UnityEngine; using UnityEngine.Events; using Random = System.Random; public class PlayerAttack : MonoBehaviour { private InputManager _inputManager; private LayerMask _enemyLayermask; private Animate _animate; private Collider _hurtbox; private string[] _availableAttacks; private float _baseDamage; private float _comboStep; private AnimationCurve _comboCurve; public void initialize(InputManager inputManager, LayerMask enemyLayermask, Animate animate, Collider hurtbox, string[] availableAttacks, float baseDamage, float comboStep, AnimationCurve comboCurve) { _inputManager = inputManager; _enemyLayermask = enemyLayermask; _hurtbox = hurtbox; _animate = animate; _availableAttacks = availableAttacks; _baseDamage = baseDamage; _comboStep = comboStep; _comboCurve = comboCurve; OnEnable(); } #region Event Setup private void OnEnable() { if (_animate != null) { _animate.OnReset += _onResetHandler; _animate.OnStartDamage += _onStartDamageHandler; _animate.OnEndDamage += _onEndDamageHandler; _animate.OnAnimationEnd += _onAnimationEndHandler; } _canAttack = true; _attacking = false; _damageEnded = true; _currentDamageMultiplier = new Dictionary(); } private void OnDisable() { _animate.OnReset -= _onResetHandler; _animate.OnStartDamage -= _onStartDamageHandler; _animate.OnEndDamage -= _onEndDamageHandler; _animate.OnAnimationEnd -= _onAnimationEndHandler; } private void _onResetHandler() { _canAttack = true; } private void _onAnimationEndHandler() { _attacking = false; _currentDamageMultiplier = new Dictionary(); } private void _onStartDamageHandler() { StartCoroutine(DealDamage()); } private void _onEndDamageHandler() { _damageEnded = true; } #endregion private bool _attacking=false; private bool _canAttack = true; private int _attack = 0; public bool Attack() { if (_canAttack && _inputManager.attackPerformed) { if (_attack >= 2 || _animate.IsCurrentAnimation("Blend Tree")) { _attack = 0; } _animate.TriggerAnimation(_availableAttacks[_attack]); _canAttack = false; _attack++; _attacking = true; } return _attacking; } private bool _damageEnded = true; IEnumerator DealDamage() { List damagedColliders = new List(); _damageEnded = false; while (!_damageEnded) { Collider[] hitColliders = Physics.OverlapBox(_hurtbox.bounds.center, _hurtbox.bounds.extents, Quaternion.identity, _enemyLayermask); foreach (Collider enemy in hitColliders) { if (!damagedColliders.Contains(enemy)) { print(enemy.gameObject.GetComponent().Health); enemy.gameObject.GetComponent().Health -= CalculateDamage(enemy); damagedColliders.Add(enemy); } } yield return null; } } Dictionary _currentDamageMultiplier = new Dictionary(); float CalculateDamage(Collider enemy) { // If enemy is hit for the first time during "Combo" he gets added to the dictionary to get its own combo mult if (!_currentDamageMultiplier.ContainsKey(enemy.GetInstanceID())) { _currentDamageMultiplier.Add(enemy.GetInstanceID(), 0f); } // If enemy gets hit again its Combo mult is incremented else { Random rnd = new Random(); _currentDamageMultiplier[enemy.GetInstanceID()] += _comboStep * (rnd.Next(1, 10) / 10f); } return _baseDamage * _comboCurve.Evaluate(_currentDamageMultiplier[enemy.GetInstanceID()]); } }