[SOLVED]Turn particle emitters on when enemy character is attacking?

I have a simple enemy in my game that follows the player and does a burn damage to the player if the player is in range. I have added a few particle emitters as children of the monster game object, and am trying to get the emitters to be off unless the player is within range of the enemy.

Here is the code I am using, but I keep getting this error in console:
Assets/Scripts/BoxMonsterAttack.cs(20,17): error CS0029: Cannot implicitly convert type UnityEngine.EllipsoidParticleEmitter[ ]' to UnityEngine.EllipsoidParticleEmitter’

I have tried everything I can think of with line 20.
Could someone tell me what I am doing wrong here? There are two Ellipsoid Particle Emitters, that are children of a child object of the monster object.

using UnityEngine;
using System.Collections;

public class BoxMonsterAttack : MonoBehaviour
{
     public int burnDamage = 10;
     GameObject player;
     PlayerHealth playerHealth;
     bool playerInRange;
     float timer;
     EllipsoidParticleEmitter emit; //not sure if i should be using particlesystem or particleemitter...




     void Awake ()
     {
          player = GameObject.FindGameObjectWithTag ("Player");
          playerHealth = player.GetComponent <PlayerHealth> ();
          emit = this.GetComponentsInChildren<EllipsoidParticleEmitter>();
          emit.enabled = false;
     }

     void OnTriggerEnter (Collider other)
     {
          if(other.gameObject == player)
          {
               playerInRange = true;
               emit.enabled = true;
          }
     }

     void OnTriggerExit (Collider other)
     {
          if(other.gameObject == player)
          {
               playerInRange = false;
               emit.enabled = false;
          }
     }

     void Update ()
     {
           timer += Time.deltaTime;
           if(playerInRange)
          {
               Burn ();
          }
      }

     void Burn ()
     {
          if(playerHealth.health > 0)
          {
               playerHealth.TakeDamage (burnDamage * Time.deltaTime);
          }
     }
}

This is the single object and GetComponentsInChildren() returns an array.
So you need an array too:

EllipsoidParticleEmitter[] emitters;

And then replace

emit.enabled=true / false;

with

foreach (EllipsoidParticleEmitter emit in emitters)
{
    emit.enabled=true / false;
}
1 Like

Ah thank you! I was wondering if it had something to do with an array and was trying all sorts of “foreach” references and such.

Now I am getting an error telling me that I can’t use .enabled in this way. Anyone know the easiest way to just use .enabled while referencing these components?

error CS1061: Type UnityEngine.EllipsoidParticleEmitter[ ]' does not contain a definition for enabled’ and no extension method enabled' of type UnityEngine.EllipsoidParticleEmitter[ ]’ could be found (are you missing a using directive or an assembly reference?)

You need to set .enabled for each emitter in emitters

emitters = this.GetComponentsInChildren<EllipsoidParticleEmitter>();
1 Like

This looks right, but now I am getting an error that i’ve never seen before.

Assets/Scripts/BoxMonsterAttack.cs(22,18): error CS0135: `emit’ conflicts with a declaration in a child block

using UnityEngine;
using System.Collections;

public class BoxMonsterAttack : MonoBehaviour
{
     public int burnDamage = 10;

     GameObject player;
     PlayerHealth playerHealth;
     bool playerInRange;
     float timer;
     EllipsoidParticleEmitter[] emit;
     EllipsoidParticleEmitter[] emitters;


     void Awake ()
     {
          player = GameObject.FindGameObjectWithTag ("Player");
          playerHealth = player.GetComponent <PlayerHealth> ();

          emit = this.GetComponentsInChildren<EllipsoidParticleEmitter>();
          emitters = this.GetComponentsInChildren<EllipsoidParticleEmitter>();

          foreach (EllipsoidParticleEmitteremitinemitters)
          {
               emit.enabled= false;
          }
     }

You need only emitters array and emit is just local variable for each emitter in emitters

using UnityEngine;
using System.Collections;
public class BoxMonsterAttack : MonoBehaviour
{
     public int burnDamage = 10;
     GameObject player;
     PlayerHealth playerHealth;
     bool playerInRange;
     float timer;
     EllipsoidParticleEmitter[] emitters;
     void Awake ()
     {
          player = GameObject.FindGameObjectWithTag ("Player");
          playerHealth = player.GetComponent <PlayerHealth> ();
          emitters = this.GetComponentsInChildren<EllipsoidParticleEmitter>();
          foreach (EllipsoidParticleEmitter emit in emitters)
          {
               emit.enabled= false;
          }
     }
1 Like

Well thank you, this works. The only thing I guess I’m not understanding is where are we defining emit? I’m not clear how the script is knowing what emit is?

We define it inside the foreach as some kind of temp local reference:

Please see foreach usage in this tutorial :wink:

1 Like

Ah thank you. I will check it out. I just played with the code and now see how it is working.

“foreach(EllipsoidParticleEmitter emit in emitters)” is basically saying “for each EllipsoidParticleEmitter, which we will call emit, that was found in emitters, do the following”

Thanks again! Three weeks into learing C# so something new every day!

Marking this as solved, although it turns out this still isn’t perfect. When the emitters are disabled, any particles that they had already created pause and exist in the world until the emitters are enabled again.

Try to call

emit.ClearParticles();

before

emit.enabled=false;
1 Like

Alright I got this working! Instead of going for emit.enabled true/false, I used emit.maxEmission. This allowed me to cut the number of particles being emittied to zero, while allowing the particle emitter to run it’s business and clear the existing particles.

foreach (EllipsoidParticleEmitteremitinemitters)
 {
emit.maxEmission= 0;
 }

Well I just posted something that worked, but again I like your solution better. My solution was a bit of a compromise, as I’d like to be able to adjust the maxEmission on each emitter individually; your solution allows me to do just that.

Thank you again.

No problem:)

1 Like

Edit; this actually makes the particle clearing very abrupt, which plays weird in game. So basically, I need to figure out how to make the enemy stop creating particles when the player leaves range, but allows the existing particles to play out their lives. The maxEmissions = 0 works for this, but means I am having to set two emitters to the same number of maxEmissions when they are active.

Hrmmm…

Oh, I see, try this

emitter.emit = false;
1 Like

by emitter I mean your emit var from foreach:)

1 Like
emit.emit = false;

did the trick

You sir, have blown my mind. thank you.