我有一个AudioManager.cs脚本,可以使用Singleton模式。从我的SplashController.cs脚本中,我尝试播放音频剪辑AudioManager.Instance.PlayMusic(intro);
,但此行NullReferenceException: Object reference not set to an instance of an object
出现错误,因为我做了Debug.Log(introClip);
我已经检查了游戏正在运行,并且musicSource = gameObject.AddComponent<AudioSource>() as AudioSource;
由AudioManager
创建了
在播放音频剪辑之后创建AudioSource;
可能是一个计时问题。我之前已经运行过类似的代码,但是还没有遇到这个问题。
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
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
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);
}
}
}
答案 0 :(得分:1)
您可以尝试使用懒惰的单身人士:
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;
}
}
}
答案 1 :(得分:0)
您的方法存在的问题是,派生类中的void Awake
方法将覆盖基类protected void Awake
中的Singleton<>
。
要使您的方法可行,您需要从新方法中调用基本方法:
void Awake()
{
base.Awake();
// The rest of AudioManager.Awake() here.
}