Unity資源加載的方式有:
1.腳本拖拽(本地)
2.Resources加載(本地) ★
3.AssetBundle加載(本地,遠程[www])★
本篇將使用Resources類搭建一個簡單的資源管理工具類
Resources是Unity下的特殊文件夾,使用需自行創建Resources文件夾(命名必須正確)
使用Resources文件夾就需要用到Resources類的一些方法,如下:
Resources類 | |
Load | 從Resources文件夾加載單個資源(可指定類型) |
LoadAll | 從Resources文件夾加載多個資源(可指定類型) |
LoadAsync | 異步從Resources文件夾加載單個資源 |
UnloadAsset | 從內存卸載資源 |
UnloadUnloadAssets | 卸載用不到的資源 |
Resources類主要用到Load方法,使用實例如下
1 public class Test : MonoBehaviour { 2 //預設體 3 GameObject _pre; 4 //圖片紋理 5 Texture _texture; 6 //精靈 7 Sprite _sprite; 8 //網格 9 Mesh _mesh; 10 //音頻 11 AudioClip _aud; 12 //材質 13 Material _material; 14 void Start () { 15 //獲取預設體 16 _pre = Resources.Load<GameObject>("player"); 17 //獲取材質 18 _material = Resources.Load<Material>("red"); 19 GetComponent<MeshRenderer>().material = _material; 20 //獲取聲音文件 21 _aud = Resources.Load<AudioClip>("SNOW"); 22 //動態添加一個聲音組件 23 AudioSource aud = gameObject.AddComponent<AudioSource>(); 24 aud.clip = _aud; 25 aud.playOnAwake = true; 26 aud.loop = true; 27 aud.Play(); 28 //獲取紋理 29 _texture = Resources.Load<Texture>("eff04b"); 30 GetComponent<MeshRenderer>().material.mainTexture = _texture; 31 } 32 }
但這樣寫會時代碼繁瑣,尤其當獲取很多資源的時候Star里的初始化就讓人沒法看了,所有需要建立一個有效的簡單工具類去管理
下面以管理添加音頻文件為例建立一個簡單的Resources資源管理工具類
1.首先建立一個單例腳本基類,用於管理所有的單例腳本,代碼如下:
1 using UnityEngine; 2 using System.Collections; 3 /// <summary> 4 /// 作為腳本單例的基類 5 /// </summary> 6 public class MonoSingletonBaseScr<T>:MonoBehaviour where T:MonoSingletonBaseScr<T> { 7 8 private static T instance; 9 public static T Instance 10 { 11 get 12 { 13 if (null==instance) { 14 //如果這個單例腳本不存在,說明沒有掛載 15 //但是要想使用,必須有對象掛載初始化 16 //所有我們自己創建一個空對象,掛載我們的單例腳本 17 //保證我們在使用的時候它已經被實例化 18 GameObject obj=new GameObject(); 19 instance=obj.AddComponent<T>(); 20 } 21 return instance; 22 } 23 } 24 25 protected virtual void Awake() 26 { 27 instance =this as T; 28 } 29 30 }
2.建立一個MusicController音頻管理單例腳本,繼承MonoSingletonBaseScr<T>基類
1 using UnityEngine; 2 using System.Collections; 3 4 public class MusicController :MonoSingletonBaseScr<MusicController> { 5 //播放器 6 private AudioSource aud_music; 7 //控制音量 8 public float music_Volume 9 { 10 get 11 { 12 return aud_music.volume; 13 } 14 set 15 { 16 aud_music.volume = value; 17 } 18 } 19 20 //重寫初始化方法,做准備工作 21 protected override void Awake() 22 { 23 //調用父類初始化方法 24 base.Awake(); 25 //自己的初始化 26 if (GetComponent<AudioSource>()==null) { 27 aud_music = gameObject.AddComponent<AudioSource>(); 28 } 29 else { 30 aud_music = GetComponent<AudioSource>(); 31 } 32 33 aud_music.loop = true; 34 aud_music.playOnAwake = true; 35 36 } 37 //根據音頻名稱播放音頻,定義為private保護 38 private void playMusicByName(object name,bool isRestart = false) 39 { 40 //定義一個當前的音頻 41 string currectName = string.Empty; 42 43 if (aud_music.clip!=null) { 44 currectName = aud_music.clip.name; 45 } 46 //ResourcesLoadTool為自己定義的Resources工具類 47 AudioClip clip = ResourcesLoadTool.Instance.ResourcesLoadObject<AudioClip>(name); 48 if (clip!=null) { 49 if (currectName==clip.name && !isRestart) { 50 return; 51 } 52 53 //播放新的音頻 54 aud_music.clip = clip; 55 aud_music.clip = clip; 56 aud_music.Play(); 57 } 58 else { 59 Debug.Log("加載失敗!=" + name.ToString()); 60 } 61 } 62 63 //使用方法重載 64 public void PlayeMusic(Music.musicType_Main music,bool isRestart = false) 65 { 66 playMusicByName(music, isRestart); 67 } 68 public void PlayeMusic(Music.musicType_Items music, bool isRestart = false) 69 { 70 playMusicByName(music, isRestart); 71 } 72 73 }
3.建立一個單例類的基類,以后所寫的單例類都可以繼承這個基類直接實現單例
1 public class SingletonBase<T>:System.IDisposable where T:new() { 2 private static T instance; 3 public static T Instance 4 { 5 get 6 { 7 if (null==instance) { 8 instance = new T(); 9 } 10 return instance; 11 } 12 } 13 14 public virtual void Dispose() 15 { 16 17 } 18 19 }
4.建立Resources管理單例類,繼承SingletonBase單例類基類
/// <summary> /// Resources管理單例類,繼承SingletonBase基類 /// </summary> public class ResourcesLoadTool :SingletonBase<ResourcesLoadTool> { public T ResourcesLoadObject<T>(object objname)where T:Object { //通過傳進的的聲音名字,獲取所在的枚舉類型 string enumType = objname.GetType().Name; //定義一個文件的路徑 string filePath = string.Empty; switch (enumType) { //case 后的值為Music腳本中的枚舉值,可根據需求在Music中添加 case "musicType_Main": { //給出在Unity工程中對應的路徑 filePath = "Music/Main/"+objname.ToString(); break; } case "musicType_Items": { filePath = "Music/Items/" + objname.ToString(); break; } } return Resources.Load<T>(filePath); } }
5.音頻文件地址的枚舉
/// <summary> /// 根據枚舉值來獲取Resources文件下文件路徑 /// </summary> public class Music { public enum musicType_Main { Accomplish, BGMusic, Select, Unlock } public enum musicType_Items { Ach, BGMusic01, BGMusic02, BGMusic03, BGMusic06 } }
文件路徑示例如下
現在,Resources簡單的資源管理工具類就封裝好了,后面可以根據需求添加Prefabs,Texture等等
進行測試:
建立一個Test腳本測試
1 public class MusicTest : MonoBehaviour { 2 void Start () { 3 } 4 5 6 void Update () { 7 8 if (Input.GetKeyDown(KeyCode.Q)) { 9 MusicController.Instance.PlayeMusic (Music.musicType_Main.BGMusic); 10 } 11 if (Input.GetKeyDown(KeyCode.W)) { 12 MusicController.Instance.PlayeMusic(Music.musicType_Items.BGMusic01); 13 } 14 15 } 16 }
將Test和腳本掛載到Cube上進行測試(MusicController腳本如果沒有掛載會自動創建一個空物體添加AudioSource)
摁下Q鍵會播放Resources/Music/Main下的BGMusic
摁下W鍵會播放Resources/Music/Items下的BGMusic01