Object reference not set to an instance of an object

Hello,
I’ll get straight to the point.

I have orbs across the map and when picked up, they should play a particle effect on the player for a few seconds (effect “traveling” with player). I have a few different effects and I’m not quite sure what’s the best location to put the particle effect prefab and what’s the easiest way to make it play from any script.
Any suggestions are welcome, because I have a feeling that my method down below is over complicating something really simple.

Problem:
So, I’ve made and dragged the particle prefabs onto my Player game object (it’s now a child of my Player) and disabled PlayOnAwake. Then I put a script on the particle prefab, so I can call the script anytime I want to play the particle effect. (I have 3 different particle effects that are realized just the same way, depending on the picked object)

This is the function that calls my script on the particle prefab (only last 2 lines of code matter):

```csharp

  • void OnTriggerEnter(Collider orb)
    {
    if(orb.gameObject.CompareTag(“HealthOrb”))
    {
    orb.gameObject.SetActive(false);
    currentHealth += 20;
    if(currentHealth > startingHealth)
    {
    currentHealth = startingHealth;
    }
    healthSlider.value = currentHealth;
    OrbPickUpPlay orbPickUp = new OrbPickUpPlay();
    orbPickUp.Play(true); //is this even the right way to call the script?
    }*
    ```

And this is the called script:

using UnityEngine;
using System.Collections;

public class OrbPickUpPlay : MonoBehaviour
{
    ParticleSystem orbParticles;
    AudioSource orbAudio;
    void Start()
    {
        orbParticles = GetComponent<ParticleSystem>();
        orbAudio = GetComponent<AudioSource>();
    }
    void Update()
    {

    }
    public void Play(bool orbType)
    {
        //Start();
        if(orbType == true)
        {
            orbParticles.startColor = new Color(100, 0, 0, .5f);
        }
        else if(orbType == false)
        {
            orbParticles.startColor = new Color(0, 0, 100, .5f);
        }
        orbParticles.Play();
        orbAudio.Play();
    }
}

I keep getting “Object reference not set to an instance of an object” or some “Null exception” no matter what I do. I’ve been programming for the last three weeks 10 hours a day, my brain isn’t working anymore.

Any help is much appreciated.

You’re getting a null reference exception because OrbPickUpPlay is a MonoBehaviour and you cannot construct a Monobehaviour using a constructor. To create a MonoBehaviour you need to add it to a GameObject using gameObject.AddComponent(). However, adding an OrbPickUpPlay script to a game object is not what you want to do here. You need a way of getting a reference to the correct child prefab game object. There’s many ways of doing this. Here’s a simple way that is similar to your current approach. In your player script (or whatever script has the OnTriggerEnter defined–I’m assuming that’s your player script), add a public GameObject field for each child particle effect like so:

public GameObject HealthOrbParticleEffect;

And assign these references to the corresponding child objects in the inspector. Then in your player script you can write:

private void PlayParticleEffect(GameObject particleObject)
{
    if (particleObject == null)
    {
        return;
    }
    ParticleSystem orbParticles = particleObject.GetComponent<ParticleSystem>();
    AudioSource orbAudio = particleObject.GetComponent<AudioSource>();
    if (orbParticles != null)
    {
        orbParticles.Play();
    }
    if (orbAudio != null)
    {
        orbAudio.Play();
    }
}

And replace the lines:

OrbPickUpPlay orbPickUp = new OrbPickUpPlay();
orbPickUp.Play(true);

With:

PlayParticleEffect(HealthOrbParticleEffect);

And this way you don’t need the OrbPickUpPlay script.

2 Likes

Working just fine, wondering why didn’t I think of that sooner, done stuff this way already
Thank you very much! :smile: