[英]Unity playing AudioClip Null Reference
I have an AudioManager.cs script which I use the Singleton pattern with. 我有一个AudioManager.cs脚本,可以使用Singleton模式。 From my SplashController.cs script I an trying to play an audio clip
AudioManager.Instance.PlayMusic(intro);
从我的SplashController.cs脚本中,我尝试播放音频剪辑
AudioManager.Instance.PlayMusic(intro);
;。 but I get an error with this line NullReferenceException: Object reference not set to an instance of an object
The audio files does exist because I do a Debug.Log(introClip);
但此行出现错误
NullReferenceException: Object reference not set to an instance of an object
音频文件确实存在,因为我执行了Debug.Log(introClip);
I have checked while the game is running and the musicSource = gameObject.AddComponent<AudioSource>() as AudioSource;
我已经检查了游戏正在运行,并且将
musicSource = gameObject.AddComponent<AudioSource>() as AudioSource;
is created by the AudioManager
由
AudioManager
创建
Could it be a timing issue where the AudioSource;
AudioSource;
是否可能是时间问题AudioSource;
is created after the audio clip is being played. 在播放音频剪辑后创建。 I have run similar code before and I have not run onto this issue.
我之前已经运行过类似的代码,但是还没有遇到这个问题。
AudioManager.cs AudioManager.cs
using UnityEngine;
using System.Collections;
using UnityEngine.Audio;
public class AudioManager : Singleton<AudioManager>
{
[Header("Mixer Groups")]
public AudioMixer masterMixer;
public AudioMixerGroup masterGroup;//The master mixer group
public AudioMixerGroup musicGroup;//The music mixer group
public AudioMixerGroup sfxGroup; //The sfx mixer group
public int lowestDeciblesBeforeMute = -20;
AudioSource musicSource; //Reference to the generated music Audio Source
AudioSource musicSource2; //Reference to the generated music Audio Source
AudioSource sfxSource; //Reference to the generated sfx Audio Source
private float musicVolume = 1;
// Multiple musics
private bool firstMusicSourceIsActive;
#region Public Enums
public enum AudioChannel { Master, Music, Sfx }
#endregion Public Enums
void Awake()
{
//Generate the Audio Source "channels" for our game's audio
musicSource = gameObject.AddComponent<AudioSource>() as AudioSource;
musicSource2 = gameObject.AddComponent<AudioSource>() as AudioSource;
sfxSource = gameObject.AddComponent<AudioSource>() as AudioSource;
//Assign each audio source to its respective mixer group so that it is
//routed and controlled by the audio mixer
musicSource.outputAudioMixerGroup = musicGroup;
musicSource2.outputAudioMixerGroup = musicGroup;
sfxSource.outputAudioMixerGroup = sfxGroup;
// Make sure to enable loop on music sources
musicSource.loop = true;
musicSource2.loop = true;
}
// Play a single clip through the sound effects source.
public void PlaySfx(AudioClip clip)
{
sfxSource.PlayOneShot(clip);
}
// Play a single clip through the music source.
public void PlayMusic(AudioClip clip)
{
musicSource.clip = clip;
musicSource.Play();
}
}
SplashController.cs SplashController.cs
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SplashController : MonoBehaviour {
public float waitTime = 5;
public AudioClip introClip;
// Use this for initialization
void Start () {
Debug.Log(introClip);
AudioManager.Instance.PlayMusic(introClip);
StartCoroutine(LoadMenu());
}
private IEnumerator LoadMenu()
{
yield return new WaitForSeconds(waitTime);
SceneManager.LoadScene(1);
}
}
Singleton.cs Singleton.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
public static T Instance { get; private set; }
protected void Awake()
{
if (Instance == null)
{
Instance = this as T;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
}
You could try using a lazy singleton: 您可以尝试使用惰性单例:
using UnityEngine;
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
protected static T instance;
public static T Instance
{
get
{
if (instance == null)
{
instance = (T)FindObjectOfType(typeof(T));
if (instance == null)
{
Log.Error("An instance of " + typeof(T) + " is needed in the scene, but there is none.");
}
}
return instance;
}
}
}
The problem with your approach is that the void Awake
method in the derived class is overriding the protected void Awake
in the base Singleton<>
class. 您的方法的问题在于,派生类中的
void Awake
方法将覆盖基Singleton<>
类中protected void Awake
。
To make your approach work, you need to call the base method from the new one: 为了使您的方法可行,您需要从新方法中调用基本方法:
void Awake()
{
base.Awake();
// The rest of AudioManager.Awake() here.
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.