Unity资源基础

发表于2016-10-11
评论0 5.7k浏览
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

Gad游戏开发核心用户群

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引