首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Unity2D开发入门-资源管理器及音频播放

Unity2D开发入门-资源管理器及音频播放

作者头像
码客说
发布2023-07-26 14:24:48
发布2023-07-26 14:24:48
4030
举报
文章被收录于专栏:码客码客

前言

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

其中GameObject挂载GameStart脚本并保证不被销毁

代码语言:javascript
复制
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目录下

代码语言:javascript
复制
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);
        }
    }
}

加载音乐

我们创建一个音效管理器,用来管理音乐的播放和音效的播放。

代码语言:javascript
复制
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
}

这样如果播放背景音乐我们可以调用

代码语言:javascript
复制
SoundManager.Instance.PlayMusic("Music/Organix");

如果播放音效可以调用

比如我这里射击键是J,按J的时候播放射击音效

代码语言:javascript
复制
if (Input.GetKeyDown(KeyCode.J))
{
    SoundManager.Instance.PlaySound("Sound/gun/pistol");
}

注意文件的目录结构为

Assets => Resources => Music => Organix.mp3 Assets => Resources => Sound=> gun => pistol.mp3

也就是说我们必须要把加载的资源放在Assets/Resources目录下

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-07-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 资源管理器
  • 加载音乐
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档