using System; using System.Collections; using System.Collections.Generic; using System.Threading.Tasks; using UnityEditor.Experimental.GraphView; using UnityEngine; public class EntityAnimation : MonoBehaviour { enum AnimationForms { Attack, SpecialAttack, Death, TakenHit } [Header("Animation and Sound Components")] [SerializeField] private Animator animator; [SerializeField] private SpriteRenderer rendererTransfer; [SerializeField] private AnimationClip idleClip; [SerializeField] private List<AnimationForms> animationIndicators; [SerializeField] private List<AudioClip> attackingSounds; [SerializeField] private List<AudioClip> damagedSounds; [SerializeField] private List<AudioClip> dyingSounds; [SerializeField] private List<AudioClip> killedCompSounds; private bool animationRunning; private SpriteRenderer spriteRenderer; public Animator AcquireAnimator() => this.animator; private void Start() { spriteRenderer = animator.GetComponent<SpriteRenderer>(); if (TryGetComponent<Enemy>(out _)) { if (Globals.IsBossEncounter && this.TryGetComponent(out Boss _)) SetSpriteLayer(10); else if (Globals.IsBossEncounter && this.TryGetComponent(out Enemy _)) SetSpriteLayer(20); else SetSpriteLayer(); } else if (TryGetComponent<Ally>(out _)) SetSpriteLayer(); } private void SetSpriteLayer(int baseLayer = 0) { bool wasDisabled = false; if (spriteRenderer.enabled is false) { spriteRenderer.enabled = true; wasDisabled = true; } spriteRenderer.sortingOrder = transform.parent.name switch { "Enemy_Position (0)" => 0 + baseLayer, "Enemy_Position (1)" => 1 + baseLayer, "Enemy_Position (2)" => 2 + baseLayer, "Enemy_Position (3)" => 3 + baseLayer, "Member_Position (0)" => 1 + baseLayer, "Member_Position (1)" => 2 + baseLayer, "Member_Position (2)" => 3 + baseLayer, _ => 0 + baseLayer, }; if (wasDisabled) spriteRenderer.enabled = false; } public AnimationClip AcquireIdleAnimation() => this.idleClip; public bool AcquireAnimationState() => animationRunning; /// <summary> /// Searches all of the items for the desired animation type before giving the amount of animations available /// </summary> /// <param name="animationType">Type of animation desired</param> /// <returns>The number of forms of animation that is available</returns> private int DecipherAnimationTypes(AnimationForms animationType) { int counter = 0; for (int i = 0; i < animationIndicators.Count; i++) { if (animationIndicators[i] == animationType) counter++; } return counter; } /// <summary> /// Plays the default attack animation for the enemy sprite /// </summary> public void PlayAttackAnimation() { int maxParamType = DecipherAnimationTypes(AnimationForms.Attack); try { SoundManager.Instance.PlaySoundFX(attackingSounds[UnityEngine.Random.Range(0, attackingSounds.Count)]); } catch { } if (maxParamType is 1) animator.SetTrigger("Attacked"); else { int attackAnimCall = UnityEngine.Random.Range(0, maxParamType); animator.SetTrigger($"Attacked_{attackAnimCall}"); } StartCoroutine(DelayForAnimation()); } /// <summary> /// Plays the default death animation for the enemy sprite /// </summary> public void PlayDeathAnimation() { if (!this.gameObject.activeSelf) return; int maxParamType = DecipherAnimationTypes(AnimationForms.Death); try { SoundManager.Instance.PlaySoundFX(dyingSounds[UnityEngine.Random.Range(0, dyingSounds.Count)]); } catch { } if (maxParamType is 1) animator.SetBool("HasDied", true); else { int deathAnimCall = UnityEngine.Random.Range(0, maxParamType); animator.SetBool($"HasDied_{deathAnimCall}", true); } StartCoroutine(DelayForAnimation(true, "HasDied")); } /// <summary> /// Plays the default take hit animation for the enemy sprite /// </summary> public void PlayTakeHitAnimation() { int maxParamType = DecipherAnimationTypes(AnimationForms.TakenHit); try { SoundManager.Instance.PlaySoundFX(damagedSounds[UnityEngine.Random.Range(0, damagedSounds.Count)]); } catch { } if (maxParamType is 1) animator.SetTrigger("WasHit"); else { int damagedAnimCall = UnityEngine.Random.Range(0, maxParamType); animator.SetTrigger($"WasHit_{damagedAnimCall}"); } StartCoroutine(DelayForAnimation()); } /// <summary> /// Plays a laugh track or sound to indicate joy from killing a player or his allies /// Randomized, so not every kill is a laugh from the enemy /// </summary> public void PlayKilledAllySound() { int rVal = UnityEngine.Random.Range(0, 101); if (rVal < 30) return; else { try { SoundManager.Instance.PlaySoundFX(killedCompSounds[UnityEngine.Random.Range(0, killedCompSounds.Count)]); } catch { } } } /// <summary> /// Delay Coroutine for the animations that are played /// </summary> /// <returns>Indicator of complete animation loop</returns> private IEnumerator DelayForAnimation(bool isBoolparam = false, string boolName = "") { animationRunning = true; yield return new WaitForSeconds(animator.GetCurrentAnimatorStateInfo(0).length); yield return new WaitForSeconds(1f); if (isBoolparam && boolName.Equals("HasDied")) { if (TryGetComponent<Enemy>(out _)) this.gameObject.SetActive(false); else if (TryGetComponent(out Ally ally)) ally.DeactivateVisually(); else if (TryGetComponent(out Player player)) player.DeactivateVisually(); } animationRunning = false; } public SpriteRenderer AcquireSpriteRenderer() => this.rendererTransfer; public async Task PlayBossSpawnAnimation(AudioClip spawnSFX) { SoundManager.Instance.PlaySoundFX(spawnSFX); animator.SetTrigger("Spawned"); StartCoroutine(DelayForAnimation()); while (animationRunning) await Task.Yield(); } }