在游戏的初始场景中 我们创建这样的结构

其中GameObject挂载GameStart脚本并保证不被销毁
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameStart : MonoBehaviour
{
private void Awake()
{
DontDestroyOnLoad(this);
SceneManager.LoadScene("Menu");
}
[RuntimeInitializeOnLoadMethod]
public static void OnGameLoad()
{
if (SceneManager.GetActiveScene().name == "GameStart")
{
return;
}
SceneManager.LoadScene("GameStart");
}
}这样它的子物体也就不会被销毁了,两个子物体分别挂载下面的两个脚本。
这样我们就可以全局去加载资源和播放音乐了。
加载的资源要放在Assets/Resources目录下
using System.Collections;
using UnityEngine;
using UnityEngine.Events;
public class ResourceManager : MonoBehaviour
{
public static ResourceManager Instance;
private void Awake()
{
Instance = this;
}
/// <summary>
/// 同步加载
/// </summary>
/// <param name="asssetName"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T Load<T>(string asssetName) where T : Object
{
var asset = Resources.Load<T>(asssetName);
return asset is GameObject ? Instantiate(asset) : asset;
}
/// <summary>
/// 异步加载
/// </summary>
/// <param name="assetName"></param>
/// <param name="callback"></param>
/// <typeparam name="T"></typeparam>
public void LoadAsync<T>(string assetName, UnityAction<T> callback) where T : Object
{
StartCoroutine(LoadAsyncCoroutine(assetName, callback));
}
/// <summary>
/// 异步加载
/// </summary>
/// <param name="assetName"></param>
/// <param name="callback"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
private IEnumerator LoadAsyncCoroutine<T>(string assetName, UnityAction<T> callback) where T : Object
{
var request = Resources.LoadAsync<T>(assetName);
yield return request;
if (request.asset is GameObject)
{
callback(Instantiate(request.asset) as T);
}
else
{
callback(request.asset as T);
}
}
}我们创建一个音效管理器,用来管理音乐的播放和音效的播放。
using UnityEngine;
using UnityEngine.Events;
public class SoundManager : MonoBehaviour
{
private AudioSource _musicSource;
public float musicVolume = 0.2f;
private AudioSource[] _soundSource;
public float soundVolume = 1f;
private int _soundSourceIndex = 0;
public static SoundManager Instance;
private void Awake()
{
Instance = this;
// Music
MusicInit();
//Sound
SoundInit();
}
#region Music
private void MusicInit()
{
GameObject musicGameObject = new GameObject { name = "Music Source" };
musicGameObject.transform.SetParent(transform);
_musicSource = musicGameObject.AddComponent<AudioSource>();
}
public void PlayMusic(string musicPath)
{
ResourceManager.Instance.LoadAsync<AudioClip>
(
musicPath,
clip =>
{
_musicSource.clip = clip;
_musicSource.loop = true;
_musicSource.volume = musicVolume;
_musicSource.Play();
}
);
}
public void StopMusic()
{
if (_musicSource.isPlaying)
{
_musicSource.Stop();
}
}
#endregion
#region Sound
private void SoundInit()
{
_soundSource = new AudioSource[10];
for (int i = 0; i < _soundSource.Length; i++)
{
GameObject soundGameObject = new GameObject { name = "Sound Source" + i };
soundGameObject.transform.SetParent(transform);
_soundSource[i] = soundGameObject.AddComponent<AudioSource>();
}
}
public void PlaySound
(
string soundPath,
bool isLoop = false,
UnityAction<AudioSource> callback = null
)
{
ResourceManager.Instance.LoadAsync<AudioClip>
(
soundPath,
clip =>
{
AudioSource soundSource = _soundSource[_soundSourceIndex];
soundSource.clip = clip;
soundSource.loop = isLoop;
soundSource.volume = soundVolume;
soundSource.Play();
callback?.Invoke(soundSource);
_soundSourceIndex++;
_soundSourceIndex %= _soundSource.Length;
}
);
}
public void StopSound(string soundName)
{
foreach (var audioSource in _soundSource)
{
if (audioSource.isPlaying && audioSource.clip.name == soundName)
{
audioSource.Stop();
}
}
}
public void StopAllSounds()
{
foreach (var audioSource in _soundSource)
{
if (audioSource.isPlaying)
{
audioSource.Stop();
}
}
}
#endregion
}这样如果播放背景音乐我们可以调用
SoundManager.Instance.PlayMusic("Music/Organix");如果播放音效可以调用
比如我这里射击键是J,按J的时候播放射击音效
if (Input.GetKeyDown(KeyCode.J))
{
SoundManager.Instance.PlaySound("Sound/gun/pistol");
}注意文件的目录结构为
Assets => Resources => Music => Organix.mp3 Assets => Resources => Sound=> gun => pistol.mp3
也就是说我们必须要把加载的资源放在Assets/Resources目录下