unity里unity水资源包格式化什么意思

求救,Unity导入资源,把里面的的脚本文件替换了,怎么还原啊。_unity3d吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:53,491贴子:
求救,Unity导入资源,把里面的的脚本文件替换了,怎么还原啊。收藏
哭了,不小心把老的脚本导入进去了,把写了好久的脚本替换掉了,有什么办法恢复吗。求救啊
进回收站的东西能还原,复制粘贴覆盖的东西不能还原。。。LZ记得多备份啊,还有得管理好备份文件
用svn管理项目
论版本管理软件的重要性
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或/freebird92/archive//2955888.html
/bbs/article-445-1.html
AssetBundle 与 Resources的区别
Resources相当于Unity一个缺省的AssetBundle。
AssetBundle可以在使用时动态加载。
Resources.load();在没有第一次Instantiate之前没有完全加载Asset资源。所以相对AssetBundle去实例一个资源,Resources会在第一次Instantiate时出现卡顿现象。
AssetBundle 加载与释放
AssetBundle的加载方式有:AssetBundle.LoadFromFile(“”); AssetBundle.LoadFromMemorty(byte[]);及WWW方式。
AssetBunddle.LoadFromFile(“”);只有在standalone上可以使用。WWW在加载AssetBundle时,会在内部创建assetBundle实例。
当AssetBundle被加载到内存后,其实内存中只有AssetBundle文件的镜像内存。//todo 该镜像文件是AssetBundle原文件大小?
当需要具体某个Prefab等资源时,使用assetbundle.Load(“”);加载具体资源。此时内存中会存在此资源的
GameObject、shaders、材质、贴图等内存。当具体Instantiate一个资源时,会对此资源的Asset资源进行clone+引用操作。Clone的资源包括GameObject、Tranform。引用的资源包括Texture、TerrainData、Shader。引用与Clone同时存在的包括 Mesh、material、PhysicMaterial、noxss。引用的资源只是指针的指向。Clone的会重新生成新的内存。
根据AssetBundle资源的加载方式,当资源释放时,如果只是Destroy,只会释放生成这个资源时Clone的那部分内存。assetBundle.Load(“”);加载的Asset内存没有被释放,AssetBundle的镜像内存也没有被释放。所以如果在该资源被销毁时需要使用Resources.UnloadUnuseAssets();去释放没有被使用的Asset资源内存。如果该AssetBundle不会被再使用可以使用AssetBundle.Unload(true)销毁内存。AssetBundle(true);代表销毁该AssetBundle镜像内存及所加载的Asset内存。参数为false时,代表只销毁镜像内存。
下面的图片可以更形象的理解AssetBundle的加载与释放。
当场景在切换时,Unity 会自动 把托管的内存释放,这其中包括Asset内存、Instantiate内存。但不会被释放的是AssetBundle镜像内存。
assetBundle.Load如果多次加载相同的资源,除第一次,其它都会返回第一次的对象。
阅读(...) 评论()玩转Unity资源,对象和序列化
玩转Unity资源,对象和序列化
&  本文将从Unity编辑器和运行时两个角度出发,主要探讨以下两方面内容:Unity序列化系统内部细节以及Unity如何维护不同对象之间的强引用。另外还会讨论对象与资源的技术实现差别。
  译注:除非特别说明,下文中所有的“资源”均指代“Asset”。
  本文内容是理解在Unity中如何高效加载和卸载资源的基础。正确的资源管理对缩短加载时间并减少内存占用来说至关重要。今天先为大家分享上半部分内容。
  <font color="#8b. 深入理解资源和对象
  在理解Unity如何确保万无一失地管理数据之前,首先要知道Unity是如何识别并序列化数据的。首先第一点,要正确区分资源(Asset)和对象(UnityEngine.Objects)。
  资源(Asset)是硬盘中的文件,存储在Unity工程的Assets文件夹内。例如,纹理(Texture),材质(Material)和FBX文件等,它们都是资源。一些资源的数据格式是Unity原生支持的,例如材质。有些资源则需要转换为原生的数据格式后才能被Unity使用,例如FBX文件。
 UnityEngine.Object
  UnityEngine.Object,或者说以大写字母O开头的Object——对象,代表序列化数据的集合,表示某个资源的具体实例。它可以是Unity引擎使用的任何类型的资源,例如网格,Sprite,音频剪辑或动画剪辑。所有的对象(Object)都是UnityEngine.Object基类的子类。
  特殊的Object类型
  几乎所有的对象(Object)类型都是内建的,其中有两种比较特殊的类型。
  ScriptableObject为开发者提供了一套便捷的系统,供开发者自定义数据类型。这些类型可以被Unity直接序列化或反序列化,并在Unity编辑器的检视器窗口中进行操作。
  MonoBehaviour提供了链接MonoScript的容器。MonoScript是一种内部数据类型,Unity用它保存对某个特定程序集和命名空间中特定脚本类的引用,MonoScript本身不包含任何实际的可执行代码。
  一对多关系
  资源(Asset)与对象(Object)是一种一对多的关系,即一个资源文件可能会包括多个Object。
  <font color="#8b. 对象之间的引用
  所有UnityEngine.Objects都可以引用其他的UnityEngine.Objects。这里“其他的Object”可能存在于相同的资源文件中,或需要从其他资源文件导入。例如,一个材质Object通常有一个或多个纹理Object的引用。这些纹理Object一般是从一个或多个纹理资源文件中导入的(例如PNG或JPG文件)。
  序列化后,这些引用由两部分数据组成:文件GUID和本地ID。文件GUID用于识别资源(Asset)文件中目标资源(Resource)的存储位置。而本地唯一(1)的ID负责识别单个资源文件中的Object,因为一个资源文件可能会包含多个Object。
  文件GUID(.meta)
  文件GUID存储于.meta文件中。Unity会在首次导入资源文件时生成.meta文件,并和资源文件一起存储在相同的目录中。
  上述的识别和引用系统可以使用文本编辑器查看:
  创建一个全新的Unity工程,更改编辑器设置,将Edit - Project Settings - Editor中的Version Control设为Visible Meta Files,并将Asset Serialization设为文本。
  新建材质并向工程中导入一个纹理。将材质赋给场景中的一个立方体,保存场景。
  使用文本编辑器打开这个材质对应的.meta文件。在文件顶端附近会有一行被标示为“guid”,该行定义了材质资源文件的文件GUID。
  本地ID(具体文件)
  如需查看本地ID,使用文本编辑器打开材质文件,材质Object的定义大致如下:
  在上面的例子中,前面有&符号的数字就是材质的本地ID。如果这个材质的Object位于一个文件GUID为“abcdefg”的资源文件中,则该材质Object的唯一识别符就是文件GUID“abcdefg”和本地ID“2100000”的组合。
  <font color="#8b. 为什么要用文件GUID和本地ID?
  工作流程
  在Unity中,为什么要使用文件GUID和本地ID这套系统呢?答案是为稳定服务,也是为了提供一套灵活的、无关具体平台的工作流程。文件GUID提供了文件存储位置的抽象,这样一个文件GUID就对应一个具体的文件,这个具体的文件存储在什么位置也就无关紧要了。因此我们才能随意移动这个文件而不破坏所有相关Object对这个文件的引用。
  任何资源(Asset)文件中都可能含有(或通过导入产生)多个UnityEngine.Object资源(Resource),因此需要一个本地ID来对其中的Object做明确区分。
  如果与资源文件相关联的文件GUID丢失,则所有对该资源文件中的Object的引用都会被破坏。这就是必须保证.meta文件具有和资源文件相同的文件名并存储在同一目录下的原因。注意Unity会重新生成丢失或被删除的.meta文件。
  Unity编辑器维护映射表
  Unity编辑器负责维护一张文件路径与文件GUID之间关系的映射表。只要资源文件被读取或导入,这个映射关系就会被建立,映射会将资源的具体位置和资源的文件GUID进行关联。Unity编辑器处于打开状态时,假设一个文件的.meta意外丢失,并且该资源文件的路径没有改变,编辑器可以保证这个资源会被分配到相同的文件GUID。
  如果在Unity编辑器处于关闭状态时丢失.meta文件,或资源文件被移动但没有移动对应的.meta文件时,所有对资源文件中的Object的引用都会丢失。
  <font color="#8b. 复合资源和导入器
  资源导入器
  正如前面深入理解资源与对象中所说的一样,不能被Unity直接支持的资源类型必须经过导入才可以使用——使用资源导入器来完成。这些导入器是自动调用的,您也可以使用AssetImporter在脚本中调用API及其子类。例如,在导入单独的纹理资源例如PNG和JPG时,TextureImporter API提供了导入时要使用的相关设置的访问。
  导入过程最终的产物是一系列UnityEngine.Object。在Unity编辑器中,这些对象会具体表现为父资源下的多个子资源,例如作为Sprite Atlas导入的纹理材质,其下属会有多个嵌套的Sprite。每一个对象都会使用相同的文件GUID,因为它们的源数据都存储在同一个资源文件中。它们在纹理资源中的具体区分工作则使用本地ID来完成。
  Library文件夹
  导入过程中会将源资源转换为匹配Unity编辑器中选定的目标平台的格式。导入过程可能会牵涉一些重量级操作,例如纹理压缩。如果每次打开Unity编辑器时都要执行这些操作,那效率就太低了。
  为了解决这一问题,我们将资源导入的结果缓存在Library文件夹中。具体就是,导入进程的结果将会存储在以资源文件GUID头两位作为名称的文件夹中。这些文件夹位于 Library/metadata/ 目录下。各个不同的对象会被序列化后存储在一个二进制文件中,文件使用资源文件的GUID来命名。
  这对所有资源都是一样的,不仅仅是非原生资源。只不过Unity原生支持的资源不需要对其进行转换或序列化处理。
  上半部分的内容主要介绍了资源(Asset)和对象(UnityEngine.Objects)的区别,以及文件GUID和本地ID二者的关联和差异。下半部分将为大家介绍第三种ID:对象的实例ID,并看看这些ID对资源在内存与显存中的加载和卸载分别有着怎样的作用。
  Footnotes(脚注)
  在文件中,本地ID是唯一的。即在一个资源文件中,里面包含的本地ID都是不重复的。
  在内部,这种缓存被称为PersistentManager。实际的转换工作在在Unity的C++ Remapper类中进行,Remapper类没有提供任何C# API调用接口。
  运行时创建资源的示例是在脚本中创建Texture2D对象:var myTexture = new Texture2D();
  程序运行时对象并没有被卸载却被从内存中移除的情况通常会发生在Unity失去了对图形内容的控制的时候。例如,当手机应用被挂起并被强制在后台运行。这种情况下,手机操作系统通常会将所有的图形资源从GPU显存中强行卸载。之后APP再回到前台运行时,Unity不得不重新向GPU上传需要的材质、着色器和网格数据,以便恢复场景的正常渲染。
  <font color="#8b. 序列化和实例
  实例ID
  尽管文件GUID和本地ID已准备妥当,它们可以强有力地维护资源之间的关系,但还有一个问题,GUID比较效率低下,我们需要为运行时准备一个效率更高的解决方案。Unity在内部维护着一个缓存表(2),负责将文件GUID和本地ID转换成为整数数值,这个数值在本次会话中是唯一的,称作实例ID。实例ID会简单地以单调递增的方式分配给缓存中新注册的对象。
  缓存负责维护实例ID与文件GUID和本地ID定义的对象源数据位置以及对象在内存中的地址(如果存在)的映射。 这样Unity就能够强而有力地保证它们互相之间的引用关系。通过解析实例ID,我们能够快速找到并返回ID对应的已载入实例。如果目标没有被加载,则Unity会通过文件GUID和本地ID解析获得对象的源数据,实时载入对象。
  启动时,实例ID缓存与所有工程内建的对象(例如在场景中被引用),以及Resources文件夹下的所有对象,都会一起被初始化。如果在运行时(3)导入了新的资源,或从AssetBundle中载入了新的对象,缓存会被更新并为这些对象添加相应条目。实例ID仅在失效时才会被从缓存中移除,当提供了指定文件GUID和本地ID的AssetBundle被卸载时就会产生移除操作。
  卸载AssetBundle会使实例ID失效,实例ID与其文件GUID和本地ID之间的映射会被删除以便节省内存。重新载入AssetBundle后,载入的每个对象都会获得一个新的实例ID。
  关于AssetBundle隐式卸载的更深层次讨论,参考AssetBundle Usage Patterns中的管理已加载资源章节。
  注意事项(IOS上挂起状态)
  注意在某些平台上,有一些系统事件会使得对象在内存中被强行卸载。例如iOS平台上,当一个app处于挂起状态时,图形资源就会从显存中卸载。如果这些对象都来自于一个已被卸除的AssetBundle时,Unity将无法再次从源数据处加载这些对象。任何已有的对这些对象的引用都会失效。这个例子中,导致的后果就是出现网格不可见(丢失),或模型的纹理和材质呈现为洋红色(Shader丢失)。
  提示:在运行时,对上述控制流程的描述并非完全准确。文件GUID和本地ID的比较操作在载入负担较重时的效率也会下降。构建Unity工程时,文件GUID和本地ID,确切地说会被映射到一种更简单的格式中。不过概念还是大致相同的,在考虑“运行时”的时候以文件GUID和本地ID的工作方式为思路还是有一些参考意义的。
  这也是在运行时资源的文件GUID无法被调取的原因。
  1.6.MonoScripts
  理解MonoBehaviour很重要的一点是知道它有一个对MonoScript的引用。MonoScript的用途非常简单,里面包括了定位某个具体的编程类所需要的信息。这两种对象都没有程序类的可执行代码。
  一个MonoScript含有三个字符串:程序库名称,类名称,命名空间。
  程序库(dll)
  构建工程时,Unity会收集Assets文件夹中独立的脚本文件并将它们编译,组成一个Mono程序库。要特别说明的是,Unity会将Assets目录中的语言分开编译,Assets/Plugins目录中的脚本同理。Plugins子目录之外的C#脚本会放在Assembly-CSharp.dll中。而Plugins及其子目录中的脚本则放置在Assembly-CSharp-firstpass.dll中,以此类推。
  这些程序库(加上预编译好的DLL程序库)将被包含在最终构建的Unity应用程序中。这些程序库都会被MonoScript所引用。与其他类型的资源不同,Unity应用程序中的所有应用程序都会在程序第一次启动时被加载。
  MonoScript就是为什么AssetBundle(或一个场景,一个Prefab)中的MonoBehaviour组件不包含有任何实际可执行代码的原因。这样就可以让不同的MonoBehaviour引用某个共享类,即便这些MonoBehaviour不在同一个AssetBundle中。
  1.7.资源(Resource)生命周期
  UnityEngine.Objects从内存中加载或卸载的时间点是定义好的。为了缩短程序载入时间,管理应用程序的内存足迹,理解UnityEinge.Object的资源生命周期是很重要的。
  加载UnityEngine.Object的两种方式
  有两种加载UnityEngine.Object的方式:自动加载或外部加载。
  当对象的实例ID与对象本身解引用,对象当前未被加载到内存中,而且可以定位到对象的源数据,此时对象会被自动加载。对象也可以外部加载,通过在脚本中创建对象或调用资源加载API来载入对象(例如AssetBundle.LoadAsset)。
  对象加载后,Unity会尝试修复任何可能存在的引用关系,通过将每个引用的文件GUID和本地ID转化成为实例ID的方式。
  一旦对象的实例ID被解引用且满足以下两个标准时,对象会被强制加载:
  实例ID引用了一个没有被加载的对象。
  实例ID在缓存中存在对应的有效GUID和本地ID。
  这种情况通常会在引用被加载并解析后很短的一段时间内发生。
  如果文件GUID和本地ID没有实例ID,或一个已卸载对象的实例ID引用了非法的文件GUID和本地ID,则引用本身会被保留,但实际对象不会被加载。在Unity编辑器中表现为“(空)”引用。在运行的应用程序中,或场景视图里,“(空)”对象通常以多种方式表示,这取决于丢失对象的类型:网格会变得不可见,纹理呈现为洋红色等等。
  对象被卸载的三种情况
  对象被卸载有以下三种情况:
  闲置资源清理进程开始后,一些对象会被自动卸载。该过程通常会在切换场景切不保留原场景(例如调用了非叠加的场景切换API Application.LoadLevel),或者脚本中调用了Resources.UnloadUnusedAssets时自动触发。该进程仅卸载没有被引用的对象:对象仅在Mono变量不存在对其的引用,且不存在引用该对象的其他活动对象时被卸载。
  Resources目录中的对象可以通过调用Resources.UnloadAsset API主动卸载。卸载后对象的实例ID会保持可用状态,对文件GUID和本地ID的条目会被保留且仍然有效。如果有Mono变量或其他有指向该对象的活动对象引用了被Resources.UnloadAsset卸载的对象,则该对象会在任意有效的引用被解引用时立刻重新加载。
  调用AssetBundle.Unload(true) API时,加载自AssetBundle的对象会被立刻自动卸载。该操作会释放对象实例ID的文件GUID和本地ID引用,任何对卸载对象的引用都会变成“(空)”引用。C#脚本中,任何试图访问已卸载对象上的方法和属性都会导致抛出空引用异常(NullReferenceException)。
  如果调用了AssetBundle.Unload(false),被卸载的AssetBundle中仍然处于激活状态的对象不会被回收,但Unity会释放其实例ID的文件GUID和本地GUID引用。之后假如它们被从内存中卸载,只剩下对这些被卸载对象额引用,Unity无法再次重新加载这些对象(4)。
  <font color="#8b.载入大型结构树(Hierarchies)
  当序列化含有大量Unity游戏对象的结构树时(例如序列化Prefab),要记住一点,即整个结构树都会被完全序列化。这就是说,结构树中的每一个游戏对象和组件都会在序列化数据中单独表示。这会对游戏对象结构的载入与实例化的耗时带来有趣的影响。
  假设一个代码块实例化了一定数量的游戏对象,结构树非常庞大的单个Prefab的实例化,会比分别实例化结构树的多个模块然后运行时组合花费更多的CPU时间。
  深度分析底层数据后发现,实例化和唤醒游戏对象所花费的CPU时间在各种情况下大致是相同的,单个独立的Prefab的实例化和唤醒仅需非常少量的CPU时间(因为不需要tranmpolining和SendTransformChanged回调)。但是,这些细小的时间节省相对于花在读取和序列化数据上的时间是很不值的。
  正如之前提到的,序列化单独的Prefab时,每个游戏对象和其组件都会被分开序列化——即便数据是重复的。一个有30个独立元素的UI界面中,Unity会为这些元素序列化30次,这就会产生大量的序列化数据。载入时,所有30个重复元素的游戏对象和组件在被转化为新实例对象之前都需要从硬盘中进行读取。正是这里讨论的读取时间决定了实例化大型Prefab的性能花销。
  Unity支持嵌套Prefab之后,对于有载入大型结构体游戏对象需求的工程而言,要想减少这类工程的载入时间,可以考虑将大型Prefab中的可重用元素分开存储到不同的Prefab中,并在运行时对它们进行实例化,而不是完全依靠Unity的序列化和Prefab系统。
  Footnotes(脚注)
  在文件中,本地ID是唯一的。即在一个资源文件中,里面包含的本地ID都是不重复的。
  在内部,这种缓存被称为PersistentManager。实际的转换工作在在Unity的C++ Remapper类中进行,Remapper类没有提供任何C# API调用接口。
  运行时创建资源的示例是在脚本中创建Texture2D对象:var myTexture = new Texture2D();
  程序运行时对象并没有被卸载却被从内存中移除的情况通常会发生在Unity失去了对图形内容的控制的时候。例如,当手机应用被挂起并被强制在后台运行。这种情况下,手机操作系统通常会将所有的图形资源从GPU显存中强行卸载。之后APP再回到前台运行时,Unity不得不重新向GPU上传需要的材质、着色器和网格数据,以便恢复场景的正常渲染。
  到此整个Unity内部资源管理与对象引用及序列化的内容就结束了,希望看完本文的你对如何合理分配Unity项目结构都有了比较清晰的概念。
发表评论:
TA的最新馆藏ResourcesResources目录中的所有的资源及其引用的资源(无论是否用到)都会经过压缩的方式打包到最后的安装包中。 Assets 目录中的所有以 Resources 命名的目录都会被打包进去。 资源使用:加载:Resources.Load(assetname),assetname是相对于 Resources 目录的相对路径,并且不需要后缀名释放:先调用 Object.Destroy(如果是已经存在的GameObject),然后清空引用,最后调用Resources.UnloadUnusedAssets。StreamingAssets这个目录中的所有资源会被原封不懂的拷贝到安装包中,可以通过 Application.streamingAssetsPath来得到资源存放路径,这个路径在不同平台上的路径如下: Editor:path = Application.dataPath + &/StreamingAssets&; iOS:path = Application.dataPath + &/Raw&; Android:path = &jar:file://& + Application.dataPath + &!/assets/&; 可以通过一般的文件操作来读取这些文件,例如 File.Read,安卓上例外。 安卓上这些文件存放在一个压缩的 .jar 文件中的,这是一种压缩格式文件,因此安卓上读取不能使用文件读取函数,一般有下面两种方法。使用 WWW 或者其他支持压缩格式的API读取第一次读取的时候使用 WWW 拷贝出来,之后使用普通的文件读取方法来读取。FMOD(一个音效插件)使用的就是后一种方法。ProjectSettings这个目录中只有两个设置文件会直接引用到 Assets 中的资源:GraphicSettings.asset,会指定哪些 Shader 是一定要预先编译好的,指定的Shader一定会打到安装包中。ProjectSettings.asset,会指定哪些场景需要打包。Prefs:Special Folder Names In Your Assets Folder[ /index.php/Special_Folder_Names_in_your_Assets_Folder#.22Plugins.22 ]Unity干货(UnityTech) 
 文章为作者独立观点,不代表微头条立场
的最新文章
一般上线项目中,图片最后都占据了安装包的绝大多数空间,因此图片的压缩与否对于产品的安装包大小和运行时内存大小都起到了决定性的作用。因此我们在这里研究一下 Unity 对图片是如何进行处理的。有时候需要在编译时候进行prefab的批量修改,这样子可以在不影响其他人的情况下编译时执行。本文主要目的是想弄明白一个很简单的问题:Unity工程中的哪些资源会被打进最后的 apk 或者 ipa 中?这些资源在打进包中之后怎样才能读取到?许久不发,深感抱歉。
这里水一篇,后面几天会发出资源管理相关的内容。
另外推荐朋友的网站“小牛学堂”,可以搜索该公众号或者直接google找官网,教程做得很用心,值得学习。简要介绍了 Editor 的几种用法,包括:
- 自定义菜单
- 自定义Component
- 自定义窗口
- 资源导入自处理
P.S 第一次使用外链连到个人网站上,为了支持 markdown, 为了支持外链,后面都按照这个工作流来进行。Unity中的资源管理是较为基础和重要的一个模块,准备分两篇来介绍资源这块。
首先是资源的基础知识,介绍工程中的资源关系。
然后是 AssetBundle 部分的知识。
本文先从第一部分开始。
不传图了,建议点击 阅读原文 。这篇文章简要介绍了一下 AssetBundle 的基本知识,Unity 4.x 的 中的打包和使用。
P.S 靠自己更新的频率还是不行,后面考虑转载一下别人的文章啦。本文主要讲述图片处理在性能优化中的原理和方法。
阅读此文可以知道:
1. 纹理压缩的原理;
2. 文件压缩的作用。从这次开始准备对 uGUI 进行一次较为完整的学习,大致的计划包括:
- UI 坐标系统
- UI 事件机制
- Image 组件分析
- Layout 系统
本次来学习 UGUI 的坐标系统。本文讲解纹理压缩这块程序所需要完成的工作,包括:
- 纹理图像 alpha 通道拆分
- Shader编写支持 alpha 通道拆分
- 图片组件重写支持 alpha 通道拆分UnityTech分享Unity的使用和游戏的设计和实现技巧热门文章最新文章UnityTech分享Unity的使用和游戏的设计和实现技巧

我要回帖

更多关于 unity水资源包 的文章

 

随机推荐