调用 .Play() 后音频不播放

Audio not playing after calling .Play()

我的游戏有一个 AudioManager。当我尝试在 NPC 上播放剪辑时,它无法播放。脚本本身可以运行,因为背景音乐播放正常。

相关部分代码:

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." );
        }
    }

声音 Class:

public class Sound
{
    public string name;

    public AudioClip clip;

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

在我调用Play()之前,我总是调用setCurrentSource(),因为audioSource是当前对话中的NPC。 剪辑、音量和音调设置正确且不为空。 我发现,当我调试它时,在 Play() 某处设置断点并转到调用 audioSource.Play() 的点,然后打开检查器查看 VS Code 中的对象信息,它会播放音频.如果我只是在 audioSource.Play() 等待,它不会。 Debug语句 Debug.Log(audioSource.isPlaying) returns false.

如前所述,我可以听到音乐,所以编辑器没有静音。 具有 AudioSource 组件的游戏对象已激活。

编辑:创建音频剪辑:

    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);
    }

声音文件为 .mp3,位于 StreamingAssets 文件夹中。

您刚刚进行了编辑以显示您是如何加载音频剪辑的,我不知道您是否真的从中得到了什么。看起来你有两种不同的机制同时运行。一方面你打电话给:

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

您似乎在尝试访问本地文件,因为 you cannot use the Directory class to list files of a Web directory。另一方面,当您实际尝试获取剪辑时,您正在调用:

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

这看起来像是您在尝试做某事 web-related。但是您的 filenameDirectory.GetFiles() 的输出,同样,它不适用于网络。

既然你说你的调试语句在你尝试播放剪辑时有效:

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

我假设您实际上是在构建您的词典,这意味着 clip-loading 代码的所有其余部分可能正在运行。这让我认为您的音频剪辑实际上并未加载,您可能正在尝试播放 null 剪辑。这就是您听不到任何声音的原因。

作为故障排除步骤,请针对您的 CreateNewSound 方法尝试以下操作:

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);
}

看看这是否开始给你调试错误,它没有加载剪辑。

[已解决] 问题出在加载部分。对于 WWW,声音没有被正确创建。 我将 createAudioClips() 和 createNewSound() 更改为

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);
    }

现在可以正常使用了。