Reputation: 195
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:
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
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