Unity资源基础
发表于2016-10-11
Unity资源基础
Unity工程目录结构
一般一个纯粹的Unity工程的目录结构由三个目录组成。
Assets: 工程中的所有脚本和资源存放位置,此目录需要通过svn(或git等)进行管理;
ProjectSettings: 工程设置目录,例如哪些场景需要编译等,需要通过svn进行管理;
Library:工程编译的中间文件,包括 Atlas, Shader, metadata等,Unity运行需要,不存在会自动生成,不需要通过svn进行管理。
Asset目录内容
Asset中的内容分为两部分:
脚本:脚本如果使用C#进行代码编写一般会生成四个工程;
资源:资源可以分为三类,Resoueces目录的资源,StreamingAssets目录的资源和其他资源。
脚本以及编译顺序
脚本内容:
Assembly-CSharp-first-pass.csproj:包括了 Assets 目录下 Standard Assets, Standard Assets Pro, Plugins 三个目录里面的脚本;
Assembly-CSharp-Editor first-pass.csproj:包括了上述三个目录下 Editor 子目录里面的脚本;
Assembly-CSharp.csproj:包括了除了上述三个目录和所有 Editor目录下的其他脚本;
Assembly-CSharp-Editor.csproj:包括了其他 Editor 目录下的所有脚本。
划分成多个工程理由:
editor 和 runtime 分开,工具和游戏分开;
减少编辑的时候的编译时间,一般只会对一个工程进行修改,此时主要编译其中一个工程即可。
注意:
上述四个工程的依赖关系是,后编译的资源可以依赖于前面的工程,而不能相反;
editor 在 runtime 之后,保证 editor 工具可以访问 runtime 脚本。
脚本编译流水线
Android 平台运行时使用 mono 虚拟机,运行C#程序集,使用 JIT 编译方式;
iOS 平台使用 AOT 编译方式,最后编译成的是native 可运行代码。
资源类型
简要列举一下,具体每种类型的资源学问较多,需要单独学习。
场景(.scene)
预设(.prefab)
模型(.fbx. .3dmax …)
网格(.mesh)
动画片段(.anim)
材质(.material)
Shader(.shader)
图片精灵
纹理(Texture)
字体(Font)
资源分类
按照我的个人理解,资源就分为这两种类型:
纯资源一般是艺术家(美术)的工作结晶,直接导入 Unity 即可,Unity 通过 XXXImporter 来获取想要的数据,如Mesh, Animation, Texture等。
解释资源则是Unity为了在纯资源的基础上封装得到的资源,如Scene, Prefab等。
资源编译内容
上述三部分资源最终会被打包到工程中:
Assets/xxx/Resources 目录中的内容, Unity会自动将资源的依赖和依赖关系打到安装包中;
Assets/StreamingAssets 会原封不动的拷贝到安装包中;
ProjectSettings中相关的Scenes以及GraphicSettings中的Shaders。
场景加载方法
这个前面有讲过,这里就不细述了。3D游戏一般都采用上述方式进行场景加载。
Resources目录资源动态加载和卸载
Resources.Load 可以加载 Resources 目录中的一个资源,参数以 Resources 目录为根目录,且不需要后缀名,然后Unity也提供了异步加载资源的方法;
Resources.UnloadAsset可以卸载上述 API 加载的资源,对 GameObject 不起作用;
Resources.UnloadUnusedAssets 可以通过 GC 方式对所有未引用的资源进行卸载;
Editor环境提供了 AssetDataBase.LoadAssetAtPath,一般在写 Editor 工具时候会用到。
StreamingAssets目录资源记载
iOS: 使用 File.Read 方法直接从 Application.streamingAssetPath 进行读取;
Android:
使用 WWW 进行读取,内容在 WWW.bytes 当中;
使用其他支持从jar包中读取资源的API进行读取;
使用WWW拷贝到document目录,然后使用 File.Read 等文件方法读取。
资源档案meta文件
每个 Assets 目录中的资源都会生成有一个meta文件“伴读”,该文件的作用有二:
Import 资源保存 ImportSetting;
保存每个资源的 guid,后文介绍。
注意该文件需要纳入SVN进行管理,否则会导致资源引用关系在不用项目成员之间发生混乱。
资源”身份证”——guid
Assets每个资源都有一个meta文件,文件中记录了一个 guid,这个guid用于记录资源之间的引用关系,引用关系在介绍到后文的 fileID 后一并介绍。
这里介绍 guid 的生成规则:
工程新import或者创建一个资源,生成 meta 文件和 guid;
删除meta文件后,重新导入资源会生成新的 meta 文件和 guid;
在 非Unity中移动资源位置,会重新生成新的 meta 文件和 guid。
另外guid的生成规则不是单纯按照目录结构或者资源内容来的,多次生成的guid是不同的,这也就是meta文件需要提交的原因,防止同一个资源在不同人的工程中生成不同的guid。
fileID和资源引用关系
首先介绍 fileID,fileID用于标识资源内部的资源。一般fileID也是直接记录在 meta 文件里面的。
资源间的依赖关系使用来确定;
资源内部的依赖关系使用 fileID。
例如我在 Unity 中创建了如下的 cube prefab,上面引用了一张贴图,贴图文件 guid 是 ec74a48d86d393d4ea70da2afd20af67,最后的prefab文件如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | %YAML 1.1 %TAG !u! tag:unity3d.com,2011: --- !u!1 &154222 GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} serializedVersion: 4 m_Component: - 4: {fileID: 454222} - 23: {fileID: 2354222} m_Layer: 0 m_Name: cube m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 --- !u!4 &454222 Transform: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} m_GameObject: {fileID: 154222} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 7.21000004, y: -5.73999977, z: 20.7999992} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 --- !u!23 &2354222 Renderer: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} m_GameObject: {fileID: 154222} m_Enabled: 1 m_CastShadows: 1 m_ReceiveShadows: 1 m_LightmapIndex: 0 m_LightmapTilingOffset: {x: .119140625, y: .119140632, z: .48975116, w: -.000483206561} m_Materials: - {fileID: 2100000, guid: ec74a48d86d393d4ea70da2afd20af67, type: 2} m_SubsetIndices: m_StaticBatchRoot: {fileID: 0} m_UseLightProbes: 0 m_LightProbeAnchor: {fileID: 0} m_ScaleInLightmap: 1 m_SortingLayerID: 0 m_SortingOrder: 0 --- !u!1001 &100100000 Prefab: m_ObjectHideFlags: 1 serializedVersion: 2 m_Modification: m_TransformParent: {fileID: 0} m_Modifications: [] m_RemovedComponents: [] m_ParentPrefab: {fileID: 0} m_RootGameObject: {fileID: 154222} m_IsPrefabParent: 1 m_IsExploded: 1 |
问题
资源被打包到安装包中后,安装后的资源目录是一个只读目录,那么安装完成后怎么添加新的资源?
Resources.Load 函数只支持从 Resources 目录加载资源。如果更新的资源存在别的地方改怎么办?
这就是本文的姊妹篇 AssetBundle基础 存在的意义,预计12月23号左右发出。
看了上面的文章 热爱游戏创作的你是不是已经开始热血沸腾了呢?是不是迫不及待的想加入游戏团队成为里面的一员呢?
福利来啦~赶快加入腾讯GAD交流群,人满封群!每天分享游戏开发内部干货、教学视频、福利活动、和有相同梦想的人在一起,更有腾讯游戏专家手把手教你做游戏!
腾讯GAD游戏程序交流群:484290331