Encounter / Assets / Scripts / EntityStateManagement / EntityAnimation.cs
EntityAnimation.cs
Raw
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();
    }
}