0

I have two scripts. The first one plays a selected sound effect; the second calls a method in the first to play the required clip.

The first script is attached to an empty GameObject and the clips are added to it:

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

public class PlaySound : MonoBehaviour
{
    [SerializeField] AudioClip[] clips; 
    public AudioSource audioSource;
    public float volume = 0.5f;

    void Start()
    {
        audioSource = GetComponent<AudioSource>();
    }
    
    public void PlayClip(int snd)
    {
        var clip = clips[snd];
        audioSource.PlayOneShot(clip, volume);
    }
}

The second script includes a declaration and a call to the PlayClip method:

    public PlaySound sound; // Script containing PlayClip method.

...

    sound.PlayClip(1);

I'm getting an error message to say that sound.PlayClip(1) needs an object reference, but I thought that was taken care of in PlaySound().

What am I not understanding?

Thanks.

Pezza
  • 23
  • 1
  • 6
  • Are you sure that in your code it is not actually `PlaySound.PlayClip(1);` ? The error message you suggests that you are trying to call the method vis the type like if it was a `static` method while it needs an instance reference since it is not – derHugo Jan 03 '22 at 07:07
  • Thanks for your reply. Could you explain that to me, as I tried static on the PlayClip method and it generated more error messages. (I'm still feeling my way with Unity. I have a mental block with issues like this.) – Pezza Jan 03 '22 at 09:18
  • I didn't say make your method `static` .. I said it sounds like the code you show here and the code you are actually using are not the same ... the error means you are currently trying to call `PlaySound.PlayClip(1)` which you can not do since `PlayClip` is not a `static` method -> you need to have an instance of `PlaySound` like in your code above ... as you have it here in your question this code would not produce the compiler error you are apparently getting ... – derHugo Jan 03 '22 at 10:14
  • Could you include the actual complete error message you are getting? – derHugo Jan 03 '22 at 10:15
  • NullReferenceException: Object reference not set to an instance of an object TileManager+d__24.MoveNext () (at Assets/Scripts/TileManager.cs:258) UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at :0) UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator) TileManager:TileRevealed(TileAction) (at Assets/Scripts/TileManager.cs:211) TileAction:OnMouseDown() (at Assets/Scripts/TileAction.cs:30) UnityEngine.SendMouseEvents:DoSendMouseEvents(Int32) – Pezza Jan 03 '22 at 20:05
  • The error occurs only when PlayClip is executed. – Pezza Jan 04 '22 at 06:05
  • I don't think you shared the code of `TileManager` .. but please refer to [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – derHugo Jan 04 '22 at 06:45
  • What I showed in Script 2 is the relevant extract from TileManager. – Pezza Jan 04 '22 at 07:48
  • Then it looks like you didn't drag/reference/assign anything in `sound` and it is `null` ... – derHugo Jan 04 '22 at 07:50
  • Thanks. I'm not sure how that is so, but I'll try to understand how it could happen when I have the PlaySound script attached to the empty game object and I have provided the sound clips. – Pezza Jan 04 '22 at 08:00
  • An image of the empty GameObject with script attached is here: https://www.perisys.com/images/Inspector-SFX1.jpg – Pezza Jan 04 '22 at 09:17
  • the error is not coming from this `SFX1` object but rather from the `TileManager` script where you most probably forgot to reference this `SFX1` object in the field called `sound` – derHugo Jan 04 '22 at 09:19
  • That seems a likely explanation. I'll give it a go tomorrow. Thanks for all your help. – Pezza Jan 04 '22 at 09:44
  • Sorry to bother you again, but I'm going round in circles again. I provided this reference for SFX1 in Tile Manager: ``` public GameObject SFX1; ``` and to play the sound, this: ``` SFX1.GetComponent().PlayClip(1); ``` When the sound was supposed to be played I got the error in the following comment. I don't know how or why I need to assign the SFX1 variable of the TileManager script in Inspector when I've already provided the reference. Are you able to explain why? Thanks. – Pezza Jan 05 '22 at 07:10
  • Error message: UnassignedReferenceException: The variable SFX1 of TileManager has not been assigned. You probably need to assign the SFX1 variable of the TileManager script in the inspector. UnityEngine.GameObject.GetComponent[T] () (at :0) TileManager+d__24.MoveNext () (at Assets/Scripts/TileManager.cs:261) – Pezza Jan 05 '22 at 07:10
  • Sounds like you either referenced the wrong GameObect or you are referencing in a different instance of `TileManager` .. but basically it means that `SFX1` is not referenced .. in general I would directly use `public PlaySound SFX1;` and do `SFX1.PlayClip(1);` .. this ensures that you can only reference something that actually has a `PlaySound` component in the first place and rule out that `GetComponent` fails – derHugo Jan 05 '22 at 07:28
  • I tried that and got a "NullReferenceException: Object reference not set to an instance of an object". The PlaySound script is attached to the SFX1 object with the three clips added. – Pezza Jan 05 '22 at 08:51
  • Again: Make sure it is really referenced in he correct instance of `TileManager` ... to me it sounds a bit like you are looking at the Inspector of a different object than the one the exception comes from ... please add a `Debu.Log("Hello there!", this);` and check how often it is called in the console. Then when clicking on it it will also highlight the object which is logging it – derHugo Jan 05 '22 at 09:06
  • I did that and the Log said "Hello, there! UnityEngine.Debug:Log (object,UnityEngine.Object)". – Pezza Jan 05 '22 at 09:19
  • The Debug was placed just before the play sound statement. – Pezza Jan 05 '22 at 09:30
  • and only once? and when clicking it once did it highlight the correct object where the SFX1 is referenced correctly in the Inspector? – derHugo Jan 05 '22 at 09:33
  • I double-clicked the Debug statement and it sent me to the SFX1.PlayClip(1) statement, after it aborted. When I double-clicked the error, it highlighted a Controller object in the Hierarchy that I use for a different script. – Pezza Jan 05 '22 at 09:56
  • you want to click it only once ... if it highlights an object it means there is the `TileManager` script on it which is throwing the exception – derHugo Jan 05 '22 at 10:06
  • Clicking once on "Hello there" brings up the controller object in the Hierarchy. Clicking on the error message brings up nothing at all. I suspect there is confusion with object references, but I can't figure out why or how. I need to take a closer look at all the code. Thanks. – Pezza Jan 05 '22 at 10:25
  • I would rather have a closer look at your controller object and which components it has – derHugo Jan 05 '22 at 10:48
  • Thanks. It's a sprite controller and used for a separate script that attaches to TileManager. I'll look into that. – Pezza Jan 05 '22 at 18:20
  • Controller is now SpriteControl. Looking at the Inspector for SpriteControl, I saw that after the list of sprites, there were two objects: Score Label and SFX1, each of which has its own script attached to it. I don't understand why they are in Inspector. However, I set the SFX1 value to 'SFX1 (Play Sound)', the alternative being 'None'. When I ran the program, I got an ArgumentNullException with the parameter name given as 'source' (that name isn't in the script). Debug showed that the PlayClips arguments were valid. Clicking on the error message highlighted SpriteControl again. – Pezza Jan 06 '22 at 06:14

1 Answers1

0

For some reason, two audio sources needed to be set to avoid the null reference: one in the SFX1 object and the other in SpriteControl. It works now. Thanks to derHugo for all his help. I learned a lot from his advice.

Pezza
  • 23
  • 1
  • 6