Unity资源管理
Package Manager¶
- 用于管理Unity项目中所需的各种库、插件和工具包
资源加载¶
文件结构¶
资源存储¶
Resource - Resources文件夹是一个只读的文件夹,通过Resources.Load()来读取对象。 - 这里的文件会被全部打到发布包中 - 打包时会进行压缩和加密 - 适合存放 prefab 等对象
streamingAssets - 只读,资源不会被加密,是原封不动进行打包 - 适合存储一些二进制文件
Application.dataPath - 只读,防止资源数据
Application.persistentDataPath - 可读可写,存储配置文件等 - 在PC上的地址是:C:\Users\用户名 \AppData\LocalLow\DefaultCompany\test
Editor¶
- 存储的资源和脚本不会被打包进发布包,脚本也只在编辑时使用,用于存放工具类的脚本以及一些编辑时使用的 DLL
Scripts¶
- 存储游戏脚本
Scenes¶
- 存储场景数据,以及灯光烘培、导航数据等
plugins¶
- 存储第三方 SDK 以及库
Shaders¶
- 存储 shader
AssetBundle¶
- AssetBundle可以将多个资源打包为单个文件,通过StreamingAssets分发,且可以从该目录直接加载AssetBundle资源。这种方式避免了资源的解压和重组,加载速度更快。
- 先手动或通过编辑器脚本进行打包,得到 AssetBundle,用于游戏中加载以及获取数据
-
AssetBundle 可以更好的进行平台优化和按需加载
-
手动设置 assetbundle
- 一个简易的打包工具代码
- 加载
AssetBundle
的时候,如果AssetBundle
依赖了另一个AssetBundle
,则需要加载依赖的这个AssetBundle
(不加载会造成连接缺失等) - 如果依赖文件不打包进其他 assetbundle,则会被打包进该 assetbundle,也就不存在依赖问题
- 打包时可以自动生成这种依赖关系
using UnityEngine; using UnityEditor; public class BuildAB { [MenuItem("Tools/BuildAB")] public static void StartBuild() { //打包AssetBundle,输出目录Application.streamingAssetsPath BuildPipeline.BuildAssetBundles(Application.streamingAssetsPath, BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.StandaloneWindows); } }
- 加载
- 一个简单的管理系统
using UnityEngine; using System.Collections; using System.Collections.Generic; using System.IO; public class AssetBundleLoaderMgr { /// <summary> /// 初始化,加载AssetBundleManifest,方便后面查找依赖 /// </summary> public void Init() { string streamingAssetsAbPath = Path.Combine(Application.streamingAssetsPath, "StreamingAssets"); AssetBundle streamingAssetsAb = AssetBundle.LoadFromFile(streamingAssetsAbPath); m_manifest = streamingAssetsAb.LoadAsset<AssetBundleManifest>("AssetBundleManifest"); } /// <summary> /// 加载AssetBundle /// </summary> /// <param name="abName">AssetBundle名称</param> /// <returns></returns> public AssetBundle LoadAssetBundle(string abName) { AssetBundle ab = null; if (!m_abDic.ContainsKey(abName)) { string abResPath = Path.Combine(Application.streamingAssetsPath, abName); ab = AssetBundle.LoadFromFile(abResPath); m_abDic[abName] = ab; } else { ab = m_abDic[abName]; } //加载依赖 string[] dependences = m_manifest.GetAllDependencies(abName); int dependenceLen = dependences.Length; if (dependenceLen > 0) { for (int i = 0; i < dependenceLen; i++) { string dependenceAbName = dependences[i]; if (!m_abDic.ContainsKey(dependenceAbName)) { AssetBundle dependenceAb = LoadAssetBundle(dependenceAbName); m_abDic[dependenceAbName] = dependenceAb; } } } return ab; } /// <summary> /// 从AssetBundle中加载Asset /// </summary> /// <typeparam name="T">类型</typeparam> /// <param name="abName">AssetBundle名</param> /// <param name="assetName">Asset名</param> /// <returns></returns> public T LoadAsset<T>(string abName, string assetName) where T : Object { AssetBundle ab = LoadAssetBundle(abName); T t = ab.LoadAsset<T>(assetName); return t; } /// <summary> /// 缓存加载的AssetBundle,防止多次加载 /// </summary> private Dictionary<string, AssetBundle> m_abDic = new Dictionary<string, AssetBundle>(); /// <summary> /// 它保存了各个AssetBundle的依赖信息 /// </summary> private AssetBundleManifest m_manifest; /// <summary> /// 单例 /// </summary> private static AssetBundleLoaderMgr s_instance; public static AssetBundleLoaderMgr instance { get { if (null == s_instance) s_instance = new AssetBundleLoaderMgr(); return s_instance; } } }
ASS 系统¶
- 优势
- 解耦资源路径与加载逻辑:资源的路径变动不会影响到代码加载逻辑。
- 灵活的更新机制:支持差异化更新,提升用户体验,尤其适合在线游戏。
- 提升资源管理效率:跨平台和多环境配置简化了资源管理过程,适合大规模游戏开发项目。
-
提供了一种按“地址”加载资产的方法
-
也是通过AssetBundle 进行打包存储,是支持热更新的(Resource 下就是只读)
-
以 group 为单位进行分组
Assembly Definition files¶
- 将项目中的脚本划分为多个独立的程序集,每个程序集通过一个asmdef文件来定义。这样可以将代码按模块组织,不同模块之间可以独立编译和引用,可以起到加速编译的作用,并确保模块代码的安全性和独立性,减少耦合
- 主要用于大型项目的优化以及依赖管理等
-
通过Assets > Create > Assembly Definition菜单创建. asmdef 文件
- asmdef 文件的 name 属性就是程序集的名称
- 只需要在脚本文件中创建 asmdef 文件,就可以自动实现模块的划分,此外可能还需要生动设置包之间的依赖关系
- 嵌套文件夹中不同层级都可以有 asmdef,每个脚本被添加到离这个脚本最短路径的ADF中去