NullReferenceException with collisions and audio management script

I am running into an issue on a prefab’s script that is set to trigger code when it collides with another object. If the prefab is instantiated and collides with the other object normally the code works as normal and applies damage, deletes the prefab, and plays a sound but if the prefab is instantiated on top of the other object it only applies damage. How can I fix it so that even if the prefab is instantiated over the other object it still gets destroyed, plays sound, and doesn’t throw a NullReferenceException?

Prefab Script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BasicShot : MonoBehaviour
{
    public Rigidbody2D rb;
    private float speed = 15;
    public int damageValue;
    private AudioController ac;
    void Start()
    {
        ac = GameObject.Find("SoundController").GetComponent<AudioController>();
        rb = gameObject.GetComponent<Rigidbody2D>();
        rb.velocity = transform.right * speed;
    }
    private void OnTriggerEnter2D(Collider2D hitInfo)
    {
        EnemyHealth enemy = hitInfo.GetComponent<EnemyHealth>();
        if (enemy != null)
        {
            enemy.TakeDamage(damageValue);
            Destroy(gameObject);
            ac.Play("Damage");
        }
        BossHealth boss = hitInfo.GetComponent<BossHealth>();
        if (boss != null)
        {
            boss.TakeDamage(damageValue);
            Destroy(gameObject);
            ac.Play("Damage");
        }
    }
    private void Update()
    {
        if (rb.position.x > 9)
        {
            Destroy(this.gameObject);
        }
    }

}

Audio Controller:

using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;
using UnityEngine.Audio;

public class AudioController : MonoBehaviour
{
    public Sound[] sounds;

    void Awake()
    {

        DontDestroyOnLoad(gameObject);

        foreach (Sound s in sounds)
        {
            s.source = gameObject.AddComponent<AudioSource>();
            s.source.clip = s.clip;

            s.source.volume = s.volume;
            s.source.pitch = s.pitch;
            s.source.loop = s.loop;
        }
    }
    public void Play (string name)
    {
        Sound s = Array.Find(sounds, sound => sound.name == name);
        if (s == null)
        {
            Debug.LogWarning($"SOUND: {name} was not found");
            return;
        }
        s.source.Play();
    }
}

1 Answer

1

Make sure that your Destroy(gameObject) line is the last line in the function, otherwise the gameObject might be destroyed before the line "ac.Play(“Damage”) can be executed.

So instead of:

if (enemy != null)
         {
             enemy.TakeDamage(damageValue);
             Destroy(gameObject);
             ac.Play("Damage");
         }

Try:

  if (enemy != null)
                 {
                     enemy.TakeDamage(damageValue);
                     ac.Play("Damage");
                     Destroy(gameObject);
                     
                 }