Unknown Code
Unknown Code

Reputation: 37

Accessing Unity particle emitter via script

I have a particle system created, and in a certain point in my game I would like to increase the max particles.

As a result, I created a game object and attached a box 2d collider to it that fires when it comes in contact with the player. In that script, I have created a public GameObject leafParticleSystem, and dragged the particle system into it.

However, in my code, I am unable to do anything like

leafParticleSystem.maxParticles=500; 

or

leafParticleSystem.emission.rate=5.0f

My code is also saying

"MissingComponentException: There is no 'ParticleSystem' attached to the "Herld" game object, but a script is trying to access it.
You probably need to add a ParticleSystem to the game object "Herld". Or your script needs to check if the component is attached before using it.untime/Export/Coroutines.cs:17)"

However, this "Herld" GameObject is not the particle system (nor do I want to add one to it) It however, does have the script attached which I am dragging the particle system (leaf particle system) to. I am just trying to modify the leaf particle system from my code in the "Herld" object.

Would appreciate if I could get any assistance

Script Attached

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class WindEffect : MonoBehaviour {
//  Rigidbody2D _rigidbody;
    // Use this for initialization

    //Storm Warning
    public GameObject AOE;
    public GameObject UIStormInterface;
    public GameObject UIWindZone;

    public GameObject LeafStormParticleSystem;


    public float ActivateFor=5.0f;
    public float stormLength=5.0f; 


    void Start () {

    }

    // Update is called once per frame
    void Update () {

    }
    void Awake () {

//      _rigidbody = GetComponent<Rigidbody2D> ();
    }

    void OnTriggerEnter2D(Collider2D col)
    {
    // Debug.Log("Object touched trigger");
    //  Debug.Log (col.transform.name); 
        if (col.gameObject.name == "Player") {
            Debug.Log ("Collided with Storm Herald");
            StartCoroutine (TemporarilyActivateStormWarning (ActivateFor));

        }
    }

    private IEnumerator TemporarilyActivateStormWarning(float ActivateFor) {
    //Show Storm Warning
        this.gameObject.GetComponent<BoxCollider2D>().enabled=(false);
        UIStormInterface.GetComponent<Text>().text="A Violent Storm is Approaching";
        UIStormInterface.SetActive(true);

        UIWindZone.SetActive (true);
        //Wait for 5 seconds then activate storm for 5 seconds
        yield return new WaitForSeconds(ActivateFor);

        UIStormInterface.SetActive(false);
        AOE.SetActive (true);

        //  ParticleSystem LeafStormParticleSystem = GetComponent<ParticleSystem>();
    //  LeafStormParticleSystem.emission.rate = 5.0f;
        LeafStormParticleSystem.maxParticles = 500;


        yield return new WaitForSeconds(stormLength);


        //Turn off Storm
        AOE.SetActive (false);
        //Tell user storm is stopped for 2 seconds.

        UIStormInterface.GetComponent<Text>().text="Storm has Passed";
        UIStormInterface.SetActive(true);
        yield return new WaitForSeconds(3);
        UIStormInterface.SetActive(false);
        UIWindZone.SetActive (false);
    }
    void OnTriggerStay2D(Collider2D col)
    {
        if (col.gameObject.name == "WindObject") {
            Debug.Log ("Collided");
            //  Debug.Log (col.transform.name); 
        //  Wind();
            //StartCoroutine(WindStart());
        }
    }
    /*
    IEnumerator WindStart(){
        Debug.LogError ("Slow Time.");

        //SlowTheTime();
    //  yield return new WaitForSeconds(3.5f);
        //  Debug.LogError ("Slow Time.");
    //  Wind ();
    }*/


    void OnCollisionEnter2D(Collision2D col)
    {
//      Debug.Log (col.transform.name); 
    }
    void OnTriggerStay(Collider col)
    {
        Debug.Log("Object is in trigger");

    }
    void OnTriggerExit(Collider other)
    {
        Debug.Log("Object left the trigger");
    }


    /*
    void Wind(){
        _rigidbody = GetComponent<Rigidbody2D> ();
        Debug.Log ("test got here");
        Debug.Log (this.gameObject.name);
        this._rigidbody.AddForce (-Vector2.left * 100 );
    }*/

}

Upvotes: 0

Views: 5363

Answers (3)

Codemaker2015
Codemaker2015

Reputation: 1

Solution 1:

Just try to change the datatype of LeafStormParticleSystem to ParticleSystem. So that you can access the methods and attributes related with particle system with the help of LeafStormParticleSystem variable

public ParticleSystem LeafStormParticleSystem;

Solution 2:

You can't directly access ParticleSystem methods and attributes of a GameObject unless and until you are not typecast that variable to ParticleSystem type.

For that you can try:

LeafStormParticleSystem.GetComponent<ParticleSystem>().maxParticles = 500;

or

((ParticleSystem)LeafStormParticleSystem).maxParticles = 500;

Upvotes: 0

Serlite
Serlite

Reputation: 12258

Presently, your LeafStormParticleSystem variable gives you a reference to the GameObject that the ParticleSystem component is on, but not the ParticleSystem itself. As a result, you can't access members of the particle system like maxParticles and emission. There are two approaches you can take to correct this:

Call GetComponent<ParticleSystem>() when you need access to the particle system. This can be costly if done too often - syntax to modify members would be:

LeafStormParticleSystem.GetComponent<ParticleSystem>().maxParticles = 500;

Change your LeafStormParticleSystem from a GameObject to a ParticleSystem. This lets you assign to LeafStormParticleSystem a direct reference to the particle system in the editor, and is more efficient than calling GetComponent() repeatedly. Syntax would be:

// Change the datatype
public ParticleSystem LeafStormParticleSystem;

// [...]
// To modify members later, you can do as you're currently doing:
LeafStormParticleSystem.maxParticles = 500;

// Modifying the emission rate is a bit less straightforward, because emission is a struct
var newEmission = LeafStormParticleSystem.emission;
newEmission.rate = new ParticleSystem.MinMaxCurve(5.0f);
LeafStormParticleSystem.emission = newEmission;

Hope this helps! Let me know if you have any questions.

Upvotes: 1

Valentin Savov
Valentin Savov

Reputation: 11

EDIT: now I see your script and...yes..you don't have a reference to the ParticleSystem

Here you do not access the ParticleSystem object, you access the GameObject that contains it: LeafStormParticleSystem.maxParticles = 500;

make a reference to the ParticleSystem itself, not the GameObject.

LeafStormParticleSystem.GetComponent<ParticleSystem>().maxParticles = 500;

OLD: you should get a reference to your particle system (in my case I stop it) for example in Start function:

private ParticleSystem ps;
void Start()
{
    ps = GetComponentInChildren<ParticleSystem>();
    ps.Stop();
}

After that you can start or edit the particles (in my case in a separate function for play and change maxParticles):

void StartEmission()
{
    ps.Play();
    ps.maxParticles = 500;
}

Upvotes: 0

Related Questions