Home > Software design >  Audio not playing after calling .Play() [SOLVED]
Audio not playing after calling .Play() [SOLVED]

Time:04-30

I have an AudioManager for my Game. When I try to play a clip on a NPC it doesn't get played. The script itself works because the background music is playing properly.

The code of the relevant parts:

using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using Random = UnityEngine.Random;

public class AudioManager : MonoBehaviour
{
    private AudioSource audioSource;
    private AudioSource backgroundPlayer;

    private Dictionary<string, Sound> audioClips;
    public List<Sound> background;

    void Start()
    {
        Sound current = background[background.Count-1];

        backgroundPlayer.clip = current.clip;
        backgroundPlayer.volume = current.volume;
        backgroundPlayer.pitch = current.pitch;
        backgroundPlayer.Play();     //works absolutely fine
    }

public void SetCurrentSource(AudioSource a)
    {
        audioSource = a;
    }

    public void Play(string name, string NPCSpeaker)
    {
        string actualName = name   "_"   NPCSpeaker;
        if (audioClips.ContainsKey(actualName))
        {
            audioSource.clip = audioClips[actualName].clip;
            audioSource.volume = audioClips[actualName].volume;
            audioSource.pitch = audioClips[actualName].pitch;
            Debug.Log("Start Audio  "   audioSource.clip);
            audioSource.Play();
            Debug.Log(audioSource.isPlaying);
        }
        else
        {
            Debug.LogWarning("AudioClip with name "  actualName   " is not found." );
        }
    }

And the Sound Class:

public class Sound
{
    public string name;

    public AudioClip clip;

    [Range(0f, 1f)]
    public float volume;
    [Range(.1f, 3f)]
    public float pitch;
}

Before I call Play(), I always call setCurrentSource() because the audioSource is the current NPC in the conversation. Clip, volume and pitch are set correctly and are not null. I found out, when I debug it, set a breakpoint in Play() somewhere and go to the point of calling audioSource.Play(), then open the inspector to view the object informations in VS Code, it will play the audio. If i just wait at audioSource.Play() it doesn't. The Debug statement Debug.Log(audioSource.isPlaying) returns false.

As said I can hear the music, so Editor isn't muted. Gameobject with the AudioSource Component is activated.

Edit: Creating the AudioClips:

    void Awake()
    {
        backgroundPlayer = gameObject.GetComponent<AudioSource>();
        createAudioClips();

        audioClips = new Dictionary<string, Sound>();
        foreach (Sound s in sounds)
        {
            audioClips.Add(s.name, s);
        }
    }
private void createAudioClips()
    {
        string rel = Application.streamingAssetsPath   "/Audio/";
        string[] paths = new string[] { rel   "Brian", rel   "Matthew", rel   "Russell", rel   "Leader", rel   "Scientist" };

        foreach (string p in paths)
        {
            foreach (string fileName in Directory.GetFiles(p))
            {
                if (Path.GetExtension(fileName) == ".mp3")
                {
                    if (p == rel   "Scientist")
                    {
                        CreateNewSound(fileName, true);
                    }
                    else
                    {
                        CreateNewSound(fileName, false);
                    }
                }
            }
        }
    }

    private void CreateNewSound(string filename, bool isScientist)
    {
        WWW request = new WWW(filename);

        string[] subs = filename.Split('\\');

        Sound newSound = new Sound();
        newSound.name = Path.GetFileNameWithoutExtension(filename);
        newSound.clip = request.GetAudioClip();
        if (isScientist)
        {
            newSound.volume = 1f;
        }
        else
        {
            newSound.volume = 0.5f;
        }
        
        newSound.pitch = 1f;
        sounds.Add(newSound);
    }

The Soundfiles are .mp3 and are in the StreamingAssets Folder.

CodePudding user response:

You just edited to show how you're loading the audio clips and I don't know if you're actually getting anything out of this. It looks like you've got two different mechanisms going at the same time. On the one hand you're calling:

foreach (string fileName in Directory.GetFiles(p))

This looks like you're trying to get to local files because you cannot use the Directory class to list files of a Web directory. On the other hand, when you actually try to get the clip, you're calling:

WWW request = new WWW(filename);
newSound.clip = request.GetAudioClip();

Which then looks like you're trying to do something web-related. But your filename is the output of Directory.GetFiles() which, again, is not for web things.

Since you're saying your debug statements are working when you try to play the clip:

The Debug statement Debug.Log(audioSource.isPlaying) returns false.

I'm going to assume that you're actually building your Dictionary, which means all the rest of the clip-loading code is probably firing. This makes me think that your audio clips are not actually getting loaded and you're probably trying to play a null clip. This would be why you're not hearing anything.

As a troubleshooting step, try the following for your CreateNewSound method:

private void CreateNewSound(string filename, bool isScientist)
{
    WWW request = new WWW(filename);

    string[] subs = filename.Split('\\');

    Sound newSound = new Sound();
    newSound.name = Path.GetFileNameWithoutExtension(filename);
    newSound.clip = request.GetAudioClip();
    // New Debug statement:
    if(newSound.clip == null)
    {
        Debug.LogErrorFormat("Failed to load a clip for {0}", filename);
    }
    // End new Debug statement
    if (isScientist)
    {
        newSound.volume = 1f;
    }
    else
    {
        newSound.volume = 0.5f;
    }
    
    newSound.pitch = 1f;
    sounds.Add(newSound);
}

See if this starts giving you Debug Errors that it's not loading the clip.

CodePudding user response:

[SOLVED] The problem is in the Loading part. With WWW the sounds didn't got created right. I changed createAudioClips() and createNewSound() to

private void createAudioClips()
    {
        string rel = "Audio";
        string[] paths = new string[] { "Brian", "Matthew", "Russell", "Leader", "Scientist" };

        foreach (string p in paths)
        {
            string abs = Path.Combine(rel, p);
            var files = Directory.GetFiles(Path.Combine(Application.dataPath, "Resources", abs));
            foreach (string fileName in files)
            {
                if (Path.GetExtension(fileName) == ".mp3")
                {
                    if (p == rel   "Scientist")
                    {
                        createNewSound(fileName, abs, true);
                    }
                    else
                    {
                        createNewSound(fileName, abs, false);
                    }
                }
            }
        }
    }

    private void createNewSound(string filename, string abs, bool isScientist)
    {
        Sound newSound = new Sound();
        newSound.name = Path.GetFileNameWithoutExtension(filename);
        string file = Path.Combine(abs, newSound.name);
        newSound.clip = Resources.Load(file) as AudioClip;
        if (isScientist)
        {
            newSound.volume = 1f;
        }
        else
        {
            newSound.volume = 0.5f;
        }
        newSound.pitch = 1f;
        sounds.Add(newSound);
    }

It work fine now.

  • Related