Arnice123
Arnice123

Reputation: 195

How to enable a particle system?

I am trying to have a explosion effect happen with a particle system when an attack animation happens. The problem is that it isn't working (Doesn't play the particle system and just deactivates). Also this is a script that is applied to all the enemies in my game not just this one that is why I have a separate script grab the particle system. If there is any code needed I can add it.

Edit: I can edit the animation however I am unsure if that is useful information.

These are the settings for the system:

enter image description here

Here are all the relevant code snippets:

public class Alk : MonoBehaviour
{
    public ParticleSystem particle;
}
    Alk alk;

    private void Start()
    {
        if (gameObject.GetComponent<Alk>() != null)
        {
            alk = gameObject.GetComponent<Alk>();
        }
    }


public void AttackPlayer(GameObject playerPos, Animator anim, NavMeshAgent agent, GameObject self, bool MultiAttack, float inRange, float inView, float AttackRange, bool isBlocking, bool HasSeenPLayer)
    {
        distDif = Vector3.Distance(self.transform.position, playerPos.transform.position);

        if (distDif >= AttackRange)
        {
            agent.SetDestination(playerPos.transform.position);
            //anim.SetBool("walk", false);
        }

        else if (distDif <= AttackRange)
        {
            anim.SetBool("walk", false);
        }

        if (MultiAttack)
        {
            MultAttack(playerPos, anim, agent, self, inRange, inView);            
        }
        else
        {
            anim.SetBool("Attack2", false);
            anim.SetBool("Attack3", false);
            StartCoroutine(PlayAnim(anim, "Attack"));
        }
        
        if (!PlayerPos.FindPlayerPos(AttackRange, playerPos.transform, inView, self, HasSeenPLayer))
        {
            anim.SetBool("Attack", false);
            anim.SetBool("Attack2", false);
            anim.SetBool("Attack3", false);
            state = State.Chase;
        }
    }

 public void MultAttack(GameObject playerPos, Animator anim, NavMeshAgent agent, GameObject self, float inRange, float inView)
    {      
        if (random == 0) random = Random.Range(1, 5);

        if (random == 1)
        {
            StartCoroutine(PlayAnim(anim, "Attack"));
            random = 0;            
            return;
        }

        if (random == 2)
        {
            if (HasParameter("Attack2", anim))
            {
                StartCoroutine(PlayAnim(anim, "Attack2"));
                random = 0;
                return;
            }

            StartCoroutine(PlayAnim(anim, "Attack"));
            random = 0;
            return;
        }
        // important code
        if (random == 3) //----------------------------------------
        {
            if (alk != null)
            {
                Debug.Log("This runs"); // does run 
                
                alk.particle.gameObject.SetActive(true);
                alk.particle.Play();
                StartCoroutine(PlayAnim(anim, "Attack3"));
                alk.particle.Stop();
                alk.particle.gameObject.SetActive(false);
                random = 0;
                return;
            }

            if (HasParameter("Attack3", anim))
            {
                StartCoroutine(PlayAnim(anim, "Attack3"));
                random = 0;
                return;
            }

            StartCoroutine(PlayAnim(anim, "Attack"));
            random = 0;
            return;
        }

        if (random == 4)
        {
            BlockPlayer(playerPos, anim, agent, inRange, inView, self);
            random = 0;
            return;
        }

        StartCoroutine(PlayAnim(anim, "Attack"));
        random = 0;
        return;

    }

    public static bool HasParameter(string paramName, Animator animator)
    {
        foreach (AnimatorControllerParameter param in animator.parameters)
        {
            if (param.name == paramName)
                return true;
        }
        return false;
    }
    IEnumerator PlayAnim(Animator anim, string booleanName)
    {
        anim.SetBool(booleanName, true);
        yield return new WaitForSeconds(anim.GetCurrentAnimatorStateInfo(0).length + anim.GetCurrentAnimatorStateInfo(0).normalizedTime);
        anim.SetBool(booleanName, false);        
    }

How it gets called (this is in another script):

void Start()
    {      

        StartCoroutine(GetGood());
    }

    IEnumerator GetGood()
    {        
        TtF.ChoseChasingWhatStateToAttackPlayer(agent, Player_pos.player, self, anim, MultiAttack, inRange, inView, AttackRange, isBlocking, hasSeenPlayer);
        
        yield return new WaitForSeconds(0.5f);
        StartCoroutine(GetGood());
    }

Upvotes: 2

Views: 415

Answers (1)

David
David

Reputation: 11

I found the problem:

alk.particle.gameObject.SetActive(true); // Activates the system
alk.particle.Play(); // Plays the particle
StartCoroutine(PlayAnim(anim, "Attack3")); // Starts Coroutine, and while it is waiting, runs the rest of the code
alk.particle.Stop(); // Immediately stops the particle
alk.particle.gameObject.SetActive(false); // and deactivates the system

The solution would be to put the code inside the coroutine, like this:

IEnumerator PlayAnim(Animator anim, string booleanName)
{
    anim.SetBool(booleanName, true);
    yield return new WaitForSeconds(anim.GetCurrentAnimatorStateInfo(0).length + anim.GetCurrentAnimatorStateInfo(0).normalizedTime);
    anim.SetBool(booleanName, false);
    if (alk != null)
    {
        alk.particle.Stop();
        alk.particle.gameObject.SetActive(false);
        random = 0;
    }
}

Upvotes: 1

Related Questions