Unity 5.5.1f Particle System

The code provided by the lecture is not compatible with Unity 5.5 (we have been warned about that)

Below is the code which I tried and eventually a solution which works but seems quite an hassle.


Unity 4 Code
as found in the lecture

void PuffSmoke () {
     GameObject smokePuff = Instantiate (smoke, transform.position, Quaternion.identity) as GameObject;
     smokePuff.particleSystem.startColor = gameObject.GetComponent<SpriteRenderer>().color;
}

Result in Unity 5.5.1f

  1. Compile Error: ‘GameObject.particleSystem’ is obsolete: ‘Property particleSystem has been deprecated. Use GetComponent() instead. (UnityUpgradable)’
  2. Compile Error: ‘Component’ does not contain a definition for ‘startColor’ and no extension method ‘startColor’ accepting a first argument of type ‘Component’ could be found (are you missing a using directive or an assembly reference?)

Unity 5.4 Code
as Suggested by Johnmcabe in Unity 5 updates thread and by Rob in ParticleSystem crossed over thread

 void PuffSmoke() {
     GameObject smokePuff = Object.Instantiate (smoke, this.transform.position, Quaternion.identity) as GameObject;
     ParticleSystem ps = smokePuff.GetComponent<ParticleSystem> ();
     var main = ps.main;
     main.startColor = this.GetComponent<SpriteRenderer> ().color;
 }

Result in Unity 5.5.1f

  1. Runtime Error: NullReferenceException: Do not create your own module instances, get them from a ParticleSystem instance
    UnityEngine.ParticleSystem+MainModule.set_startColor (MinMaxGradient value) (at C:/buildslave/unity/build/artifacts/generated/common/modules/ParticleSystem/ParticleSystemBindings.gen.cs:499)
    Brick.PuffSmoke () (at Assets/Scripts/Brick.cs:73)
    Brick.HandleHits () (at Assets/Scripts/Brick.cs:57)
    Brick.OnCollisionEnter2D (UnityEngine.Collision2D collision) (at Assets/Scripts/Brick.cs:40)

A Unity 5.5.1f solution I came up with

  1. Removed the particle system under the Smoke prefab and instead add the particle system as a component to the smoke-prefab gameobject

  2. Add a script to the Smoke prefab (in my case I called it ParticleSystemColorChanger)

  3. Within the SmokePuff function (in brick.cs) we replace thesmokePuff.particleSystem.startColor = gameObject.GetComponent().color; with so the entire function now reads like

private void PuffSmoke() {
    GameObject smokePuff = Instantiate(smoke, gameObject.transform.position, Quaternion.identity);
    smokePuff.SendMessage ("SetColor", gameObject.GetComponent<SpriteRenderer> ().color);
}
  1. Below is the ParticleSystemColorChanger script/class
using UnityEngine;
public class ParticleSystemColorChanger : MonoBehaviour
{
    void SetColor(object value)
    {
        if (value.GetType() != typeof(Color))
        {
            Debug.LogError("Incorrect value has been passed to ParticleSystemColorChanger:SetColor");
            return;
        }

        var ps = gameObject.GetComponent<ParticleSystem>();
        if (ps == null)
        {
            Debug.LogError("ParticleSystemColorChanger script has not been attached to a GameObject with a ParticleSystem");
            return;
        }

        var main = ps.main;
        main.startColor = (Color)value;
    }
}
1 Like

Hey, Thanks for your solution.
But when I am trying to run this code, it is not producing(?) any smoke. I am getting an error
"SendMessage SetColor has no receiver !
UnityEngine.GameObject: SendMessage(String, Object)"

Any Suggestions??

Thanks.

Here’s some additional info on the particle system.

Apparently the Particle System’s accessibility has changed. Instead of modifying the ParticleSystem directly, you first have to extract its “main” class. I am not completely sure why, but they have limited the access to it to read only (There is only a get modifier and not a set) Notice that Visual Studio shows this (One of the major reasons I prefer to use the newer version of Unity attached to Visual Studio because its intellisense is excellent):
image

I am not sure why they did that, but you can store the main class into a variable and access the particleSystem from the variable holding “main”. I am assuming it has something to do with it being a reference somehow. I am kind of tired so I can’t quite put together why they did this at the moment.

The two highlighted lines achieve the ability to change the particle color to the brick color in Unity 2017.1.0f3:

Here is the text so you can copy and paste it:

        //Copy our empty object with the Particle system attached and extract the main class from its ParticleSystem
        var main = Instantiate(smoke, gameObject.transform.position, Quaternion.identity).GetComponent<ParticleSystem>().main;

        //Change the new empty's particle system
        main.startColor = gameObject.GetComponent<SpriteRenderer>().color;
4 Likes

P.S. Here is that same code broken down into 3 lines instead of 2 to make it a little easier to understand, and so it looks closer the code in the video.

I have also explicitly written out the variable type you create with each line, instead of using the short hand “var” to declare the variables to make it easier to understand.

It does the exact same thing as the code above, but the code above does both of the top two lines of code at the same time, allowing it to be only 2 lines instead of 3.

        //Copy our empty object with the Particle system attached
        GameObject smokePuff = Instantiate(smoke, gameObject.transform.position, Quaternion.identity);

        //Extract the main class from the particleSystem of the smokePuff we just created
        ParticleSystem.MainModule main = smokePuff.GetComponent<ParticleSystem>().main;

        //Change the new smokePuff's particle settings using its ParticleSystem's main class
        main.startColor = gameObject.GetComponent<SpriteRenderer>().color;
3 Likes

I had similar problems with 2017.1 getting a Null Reference. Since the particle system was a child of an empty game object I needed to use GetComponentInChildren

//make smoke
GameObject smoke = Instantiate(_smoke, transform.position, Quaternion.identity);
//get access to particle system
var smokeColor = smoke.GetComponentInChildren().main;
//change smoke color to brick color
smokeColor.startColor = gameObject.GetComponent().color;

This cleared the confusion. Thanks. I am able to change the color now.

Just following up on this as the above solutions did not completely solve my problem. I also had to go into the Particle System component, and within the Renderer tab, change the Material and Trail material to the Default-Particle material (for some reason they were not already set).

ParticleSystemColor

1 Like

I was able to simplify the code in the OP; a separate script attached to the particle isn’t really necessary. Here’s what I did in my Brick.cs code.


void DestroyBrick() {
    // make smoke particles
    GameObject puff = Instantiate(smoke, gameObject.transform.position, Quaternion.identity);
    // change color of smoke
    var puffMain = puff.GetComponent<ParticleSystem>().main;
    puffMain.startColor = brickColor;
    // kill brick
    Destroy(gameObject);
    breakableCount--;
    levelManager.BrickDestroyed();
    print(breakableCount);

}

Sidenotes:

  1. HandleHits() calls DestroyBrick() when timesHit >= maxHits
  2. private Color brickColor is declared at the top and set to GetComponent<SpriteRenderer>().color in Start()

Personally I like being able to keep this in one script file rather than making another file to run a single function.

3 Likes

The code above helped me fix my orange triangle error i had about the main color of the particle system.
Thanks !!

I am redoing this course in Unity 2017.3.0f3 and have found that I also needed to set the materials in the renderer of the particle system as well as adding the code above accessing the main class of the particle system.

To add one more step I even had to set the material and trail material to the default-sprite material instead of the default particle. This caused isues with my sprites because I made them in photoshop and altering the sprites color then made all of my bricks look different.

Privacy & Terms