怎么租域名做网站,软件开发和网站开发哪个好,品牌建设部门的搭建,网站项目流程一#xff1a;资源类型 GameObject, Transform, Mesh, Texture, Material, Shader, noxss和各种其他Assets。 二#xff1a;AssetBundle文件内存镜像 来自文件就用CreateFromFile(注意这种方法只能用于standalone程序#xff09;这是最快的加载方法。也可以来自Memory,用…
一资源类型 GameObject, Transform, Mesh, Texture, Material, Shader, noxss和各种其他Assets。 二AssetBundle文件内存镜像 来自文件就用CreateFromFile(注意这种方法只能用于standalone程序这是最快的加载方法。也可以来自Memory,用CreateFromMemory(byte[]),这个byte[]可以来自文件读取的缓冲www的下载或者其他可能的方式。 其实WWW的assetBundle就是内部数据读取完后自动创建了一个assetBundle而已。Create完以后等于把硬盘或者网络的一个文件读到内存一个区域这时候只是个AssetBundle内存镜像数据块还没有Assets的概念。 CreateFromFile:这种方式不会把整个硬盘AssetBundle文件都加载到内存来而是类似建立一个文件操作句柄和缓冲区需要时才实时Load所以这种加载方式是最节省资源的基本上AssetBundle本身不占什么内存只需要Asset对象的内存。可惜只能在PC/Mac Standalone程序中使用。 CreateFromMemory和WWW.assetBundle:这两种方式AssetBundle文件会整个镜像于内存中理论上文件多大就需要多大的内存之后Load时还要占用额外内存去生成Asset对象。
三Asset内存镜像资源创建方式 1. 静态引用在脚本中加一个public GameObject变量在Inspector面板中拖一个prefab到该变量上然后在需要引用的地方Instantiate 2. Resource.Load资源需要放在Assets/Resources目录下 3. AssetBundle.Load, Load之后Instantiate。AssetBundle.Load(同Resources.Load) 这才会从AssetBundle的内存镜像里读取并创建一个Asset对象创建Asset对象同时也会分配相应内存用于存放(反序列化).异步读取用AssetBundle.LoadAsync,也可以一次读取多个用AssetBundle.LoadAll 加载资源的过程可以分为两个阶段第一阶段是使用Resources.Load或者AssetBundle.Load加载各种资源第二阶段是使用GameObject.Instantiate克隆出一个新的GameObject。 Load的资源类型包括GameObject, Transform, Mesh, Texture, Material, Shader和noxss等各种资源但是Resources.Load和AssetBundle.Load是有区别的。 前两种方式在第一次Instantiate之前相应的Asset对象还没有被创建直到第一次Instantiate时才会真正去读取文件创建这些Assets。它的目的是实现一种OnDemand的使用方式到该资源真正使用时才会去创建这些资源。 而使用AssetBundle.Load方法时会直接将资源文件读取出来创建这些Assets因此第一次Instantiate的代价会相对较小。上述区别可以帮助我们解释为什么发射第一发子弹时有明显的卡顿现象的出现。 四Instantiate Prefab 一个Prefab从assetBundle里Load出来 里面可能包括Gameobject transform mesh texture material shader script和各种其他Assets。 Instantiate一个Prefab是一个对Assets进行Clone(复制)引用结合的过程GameObject transform 是Clone是新生成的。其他mesh / texture / material / shader 等这其中有些是纯引用的关系的包括Texture和TerrainData还有引用和复制同时存在的包括Mesh/material/PhysicMaterial。引用的Asset对象不会被复制只是一个简单的指针指向已经Load的Asset对象。这种含糊的引用加克隆的混合大概是搞糊涂大多数人的主要原因。 专门要提一下的是一个特殊的东西Script Asset看起来很奇怪Unity里每个Script都是一个封闭的Class定义而已,并没有写调用代码光Class的定义脚本是不会工作的。其实Unity引擎就是那个调用代码Clone一个script asset等于new一个class实例实例才会完成工作。通过AddComponent给物体添加一个Script Assets就完成了把脚本类实例挂到Unity主线程的调用链里去的工作Class实例里的OnUpdate OnStart等才会被执行。多个物体挂同一个脚本其实就是在多个物体上挂了那个脚本类的多个实例而已这样就好理解了。在new class这个过程中数据区是复制的代码区是共享的算是一种特殊的复制引用关系。 你可以再Instantiate一个同样的Prefab,还是这套mesh/texture/material/shader…这时候会有新的GameObject等但是不会创建新的引用对象比如Texture. 所以你Load出来的Assets其实就是个数据源用于生成新对象或者被引用生成的过程可能是复制clone)也可能是引用指针 当你Destroy一个实例时只是释放那些Clone对象并不会释放引用对象和Clone的数据源对象Destroy并不知道是否还有别的object在引用那些对象。 等到没有任何游戏场景物体在用这些Assets以后这些assets就成了没有引用的游离数据块了是UnusedAssets了这时候就可以通过Resources.UnloadUnusedAssets来释放,Destroy不能完成这个任务AssetBundle.Unload(false)也不行AssetBundle.Unload(true)可以但不安全除非你很清楚没有任何对象在用这些Assets了。 五资源销毁 Destroy:主要用于销毁克隆对象也可以用于场景内的静态物体不会自动释放该对象的所有引用。虽然也可以用于Asset,但是概念不一样要小心如果用于销毁从文件加载的Asset对象会销毁相应的资源文件但是如果销毁的Asset是Copy的或者用脚本动态生成的只会销毁内存对象。 AssetBundle.Unload(false):释放AssetBundle文件内存镜像 AssetBundle.Unload(true):释放AssetBundle文件内存镜像同时销毁所有已经Load的Assets内存对象 Reources.UnloadAsset(Object):显式的释放已加载的Asset对象只能卸载磁盘文件加载的Asset对象 Resources.UnloadUnusedAssets:用于释放所有没有引用的Asset对象 GC.Collect()强制垃圾收集器立即释放内存 Unity的GC功能不算好没把握的时候就强制调用一下 六总结 Load的是Asset,Instantiate的是GameObject和Object in SceneLoad的Asset要Unload,new的或者Instantiate的object可以Destroy Texture加载以后是到内存显示的时候才进入显存的Texture Memory。 所有的东西基础都是Object 为了不出现首次Instantiate时卡顿的现象推荐使用AssetBundle.Load的方式代替Resources.Load的方式来加载资源 加载完资源后立马调用AssetBunble.Unload(false)释放文件内存镜像 Unity自身没有提供良好的内存申请和释放管理机制Destroy一个GameObject会马上释放内存而不是进行内部的缓存因此应用程序对频繁不用的对象如NPCFX等进行对象池管理是必要的减少内存申请次数 总结一下各种加载和初始化的用法: AssetBundle.CreateFrom…..创建一个AssetBundle内存镜像注意同一个assetBundle文件在没有Unload之前不能再次被使用 WWW.AssetBundle同上当然要先new一个再 yield return 然后才能使用 AssetBundle.Load(name)从AssetBundle读取一个指定名称的Asset并生成Asset内存对象如果多次Load同名对象除第一次外都只会返回已经生成的Asset对象也就是说多次Load一个Asset并不会生成多个副本singleton。 Resources.Load(path;name)同上,只是从默认的位置加载ondemond需要时再加载可能造成第一次instantiate卡顿。 Instantiateobject)Clone一个object的完整结构包括其所有Component和子物体详见官方文档,浅Copy并不复制所有引用类型。有个特别用法虽然很少这样用其实可以用Instantiate来完整的拷贝一个引用类型的Asset,比如Texture等要拷贝的Texture必须类型设置为Read/Write able。 说白了就是instantiate之后destroy并不能完全释放内存还要考虑内存中躺着的asset也不要忘了内存中可能躺着的assetbundle文件。assetbundle文件应该在生成asset后立即释放asset则最好是通过UnloadUnusedAssets释放asset到底有没有被引用则是需要注意的地方