0
\$\begingroup\$

I am working on a game and I am trying to add a sound effect.

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

public class PlayerController : MonoBehaviour
{
    private Rigidbody playerbody;
    private Animator playerAnim;
    private bool grounded;
    public bool gameover;
    public float jumpforce;
    public float gravmod;
    public ParticleSystem explosion;
    public ParticleSystem dirt;
    public AudioClip jumpSound;
    public AudioClip crashSound;
    private AudioSource playerAudio;

    // Start is called before the first frame update
    void Start()
    {
        playerbody = GetComponent<Rigidbody>();
        playerAnim = GetComponent<Animator>();
        playerAudio = GetComponent<AudioSource>();
        Physics.gravity *= gravmod;
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space) && grounded && gameover == false)
        {
            playerAudio.PlayOneShot(jumpSound, 1.0f);
            playerbody.AddForce(Vector3.up * jumpforce, ForceMode.Impulse);
            playerAnim.SetTrigger("Jump_trig");
            grounded = false;
            dirt.Stop();
        }
    }
    private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag("Ground"))
        {
            grounded = true;
            dirt.Play();
        }
        if (collision.gameObject.CompareTag("Obstacle"))
        {
            playerAudio.PlayOneShot(crashSound, 1.0f);
            gameover = true;
            playerAnim.SetBool("Death_b", true);
            playerAnim.SetInteger("DeathType_int", 1);
            explosion.Play();
            dirt.Stop();
        }
    }
}

At playerAudio.PlayOneShot, it just won't play and the rest of that part of the code stops working. It returns ArgumentNullException: Value cannot be null even though jumpSound and crashSound are both clearly defined. What is wrong?

\$\endgroup\$
3
  • \$\begingroup\$ This can happen sometimes if you have two instances of your script in your project/scene. You remembered to set the audioclips in the inspector on one, but missed assigning them on the other. \$\endgroup\$
    – DMGregory
    Nov 29, 2020 at 4:41
  • \$\begingroup\$ I used this script twice, both in other files but there is no place to specify what audio files I am using. Neither of these files call upon the audio file either. I do not think there any other instances of this file in my project. \$\endgroup\$
    – John Liu
    Nov 29, 2020 at 14:28
  • \$\begingroup\$ jumpSound & crashSound are defined, but it doesn't look like either of them has been initialized anywhere in the code. How are you setting their values (or put differently, how are you indicating what sound/file/resource they correspond to)? \$\endgroup\$
    – Pikalek
    Dec 1, 2020 at 4:56

3 Answers 3

2
\$\begingroup\$

Change your code like this:

void Start()
{
    playerbody = GetComponent<Rigidbody>();
    playerAnim = GetComponent<Animator>();
    playerAudio = GetComponent<AudioSource>();
    Physics.gravity *= gravmod;

    //log error messages indicating which GameObject is missing a reference value
    if (playerAudio == null) {
        Debug.LogError($"{nameof(playerAudio)} is null on {gameObject.name}", this);
    }
    if (playerAnim == null) {
        Debug.LogError($"{nameof(playerAnim)} is null on {gameObject.name}", this);
    }
    if (crashSound == null) {
        Debug.LogError($"{nameof(crashSound)} is null on " + gameObject.name, this);
    }
}

This will log error messages if references are missing. Logging like this should usually be the first thing you try when code isn't working like it should.

You can also use Assert.IsNotNull(), e.g.:

Assert.IsNotNull(crashSound, $"{nameof(crashSound)} is null on {gameObject.name}");
\$\endgroup\$
2
  • \$\begingroup\$ Instead of editing the code to add log spam, it's usually easier and cleaner to just set a breakpoint in your development environment and check if these objects are null in the debugger. \$\endgroup\$
    – Philipp
    Sep 15 at 11:21
  • \$\begingroup\$ @phillip Those are error conditions, so logging is justified IMO. What if one of those components accidentally gets removed in the future? This way he gets a meaningful error message instead of a generic null reference error. Additionally, it's in OnCollisionEnter(), not in Update() or OnCollisionStay(), so it's not going to spam the console with hundreds of errors. Although now that I think about it, I should have put the logging into Start(). \$\endgroup\$
    – Kevin
    Sep 15 at 18:42
1
\$\begingroup\$

I got the same error while doing the guided practice project from Unity Learn.

I have fixed it by adding an Audio Source component in the Play:

  1. Select the Play gameObject in the Hierarchy
  2. Click the Add Component button in the Inspector and select "audioSource"

Hope my answer could help other Unity learners.

\$\endgroup\$
0
\$\begingroup\$

If your sound effects are defined but the code still won't run, its possible that the game object the script is attached to has no audio source component. You can add that under the inspector manually by selecting the object in hierarchy and adding said component, as Bing said.

Here's a short tutorial clip if it helps you: https://www.youtube.com/shorts/WbuQNmbwecc

Alternatively, you could try checking if the game object has an audio source to begin with and, if it does not have an audio source, add one in script.

You could try this:

    public class PlayerController : MonoBehaviour
    {
       // Insert all your other variables above this
       public AudioClip jumpSound;
       public AudioClip crashSound;
       private AudioSource playerAudio;

       // Start is called before the first frame update
       void Start()
       {
           // This is a bool that checks if the game object has an AudioSource or not. 
           // It returns false if there is no AudioSource, and vice versa

           if(!TryGetComponent<AudioSource>(out AudioSource source)) 
           {
              gameObject.AddComponent<AudioSource>(); // 
           }
           
           // Afterwards, we can get our AudioSource the usual way
           playerAudio = GetComponent<AudioSource>(); 
       }
    }
```
\$\endgroup\$
2
  • 1
    \$\begingroup\$ "its possible that the game object the script is attached to has no audio source component" That will throw a "Null Reference Exception" or a "Missing Reference Exception" rather than an "Argument Null Exception". The "Argument" there says that it's a parameter passed into the function that's null, not the object that should own the method. \$\endgroup\$
    – DMGregory
    Sep 14 at 11:07
  • \$\begingroup\$ @DMGregory he's right. The issue is with a missing AudioSource component, but the ArgumentNullException happens only you do a PlayOneShot() on the null AudioSource for some reason (which is what the questioner does). Otherwise, it's as you say, and the error will be either a NullReferenceException or a MissingReferenceException. It seems to me like PlayOneShot() may call a static function somewhere in Unity's native code that passes the AudioSource as an argument. \$\endgroup\$
    – John Doe
    Sep 15 at 12:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .