资源加载方式有三种
2015-05-28 11:50
232 查看
资源加载方式有三种
1. 静态引用
建一个public的变量,在Inspector里把prefab拉上去,用的时候instantiate
2. 如何卸载Resources.Load()方式加载的资源,(Load以后instantiate)
Object obj = Resources.Load("MyPrefab");
GameObject instance = Instantiate(obj) as GameObject;
....
....
Destroy(instance); // 销毁了一个Prefab实例,这时候
MyPrefab已经没有被实际的物体引用了
obj = null; // 让变量obj不再引用MyPrefab
Resources.UnloadUnusedAssets();//释放已经没有引用的Asset
3. 如何卸载AssetBundle.Load()方式加载的资源,(Load以后instantiate)
AssetBundle AssetBundle1 = AssetBundle.CreateFromFile("1.unity3d");//存放于“镜像内存”中
obj1.renderer.material.mainTexture = AssetBundle1.Load("wall") as Texture;//存放于“主内存”中
// obj2与obj1指向同一个Texture
Asset
obj2.renderer.material.mainTexture = obj1.renderer.material.mainTexture;
如果AssetBundle1.Unload(true);那obj1和obj2都变成黑的了,因为指向的Texture
Asset没了
// 关闭AssetBundle但没有摧毁创建的对象和引用
如果AssetBundle.Unload(false); 那obj1和obj2不变,只是释放AssetBundle1的内存镜像
....
....
Destroy(obj1);//obj1被释放,但并不会释放刚才Load的Texture
Resources.UnloadUnusedAssets();//不会有任何内存释放
因为Texture asset还被obj2用着
Destroy(obj2);//obj2被释放,但也不会释放刚才Load的Texture
Resources.UnloadUnusedAssets();//这时候刚才load的Texture
Asset释放了,因为没有任何引用了
GC.Collect(); // 强制立即释放内存
用AssetBundle加载的asset一样可以用Resources.UnloadUnusedAssets卸载,但必须先AssetBundle.Unload,才会被识别为无用的asset
4. 场景切换
自动销毁:
a.
所有的内存对象都会被自动销毁,包括你用AssetBundle.Load加载的对象和Instaniate克隆的。
b. Unity在一个场景开始时,根据场景构成和引用关系所自动读取的资源,只有在读取一个新的场景或者reset当前场景时,才会得到清理。
不自动销毁:
a.
AssetBundle文件自身的内存镜像,那个必须要用Unload来释放,用.net的术语,这种数据缓存是非托管的。
b. 在场景之间被保持的脚本(通常这些脚本所挂载的GameObject,作为了DontDestroyOnLoad函数的参数,即被其标识为场景切换时不失效),且这些脚本很可能含有对其他物体的Component或者资源的引用,这些资源就都得不到释放。
c. static的单例(singleton)在场景切换时也不会被摧毁,如果这种单例含有大量的对资源的引用,也会成为大问题。
5. a. Load的是Asset,
销毁时:Load的Asset要Unload
b. Instantiate的是GameObject和Object
in Scene,销毁时: Instantiate的或者new的object可以Destroy
c. Texture加载以后是到内存,显示的时候才进入显存的Texture
Memory
总结:
三种加载方式的区别:
静态引用 + Resouces.load()
引用对象texture是在instantiate时加载, 第一次instantiate时会包含加载引用
assets的操作,导致第一次加载的延迟
assetBundle.Load()
会把perfab的全部assets 都加载,instantiate时只是生成Clone
a. Destroy: 主要用于销毁克隆对象,也可以用于场景内的静态物体,不会自动释放该对象的所有引用。虽然也可以用于Asset,但是概念不一样要小心,如果用于销毁从文
件加载的Asset对象会销毁相应的资源文件!但是如果销毁的Asset是Copy的或者用脚本动态生成的,只会销毁内存对象。
你Load出来的Assets其实就是个数据源,用于生成新对象或者被引用,生成的过程可能是复制(clone)也可能是引用(指针)
当你Destroy一个实例时,只是释放那些Clone(复制)对象,并不会释放引用对象和Clone的数据源对象,Destroy并不知道是否还有别的object在引用那些对象。
等到没有任何 游戏场景物体在用这些Assets以后,这些assets就成了没有引用的游离数据块了,是UnusedAssets了,这时候就可以通过 Resources.UnloadUnusedAssets来释放。
b. AssetBundle.Unload(false):释放AssetBundle文件内存镜像
c. AssetBundle.Unload(true):释放AssetBundle文件内存镜像同时销毁所有已经Load的Assets内存对象
d. Reources.UnloadAsset(Object):显式的释放已加载的Asset对象,只能卸载磁盘文件加载的Asset对象
e. Resources.UnloadUnusedAssets:用于释放所有没有引用的Asset对象
f. GC.Collect()强制垃圾收集器立即释放内存
转摘自 http://blog.sina.com.cn/s/blog_74c22b2101019u9c.html
1. 静态引用
建一个public的变量,在Inspector里把prefab拉上去,用的时候instantiate
2. 如何卸载Resources.Load()方式加载的资源,(Load以后instantiate)
Object obj = Resources.Load("MyPrefab");
GameObject instance = Instantiate(obj) as GameObject;
....
....
Destroy(instance); // 销毁了一个Prefab实例,这时候
MyPrefab已经没有被实际的物体引用了
obj = null; // 让变量obj不再引用MyPrefab
Resources.UnloadUnusedAssets();//释放已经没有引用的Asset
3. 如何卸载AssetBundle.Load()方式加载的资源,(Load以后instantiate)
AssetBundle AssetBundle1 = AssetBundle.CreateFromFile("1.unity3d");//存放于“镜像内存”中
obj1.renderer.material.mainTexture = AssetBundle1.Load("wall") as Texture;//存放于“主内存”中
// obj2与obj1指向同一个Texture
Asset
obj2.renderer.material.mainTexture = obj1.renderer.material.mainTexture;
如果AssetBundle1.Unload(true);那obj1和obj2都变成黑的了,因为指向的Texture
Asset没了
// 关闭AssetBundle但没有摧毁创建的对象和引用
如果AssetBundle.Unload(false); 那obj1和obj2不变,只是释放AssetBundle1的内存镜像
....
....
Destroy(obj1);//obj1被释放,但并不会释放刚才Load的Texture
Resources.UnloadUnusedAssets();//不会有任何内存释放
因为Texture asset还被obj2用着
Destroy(obj2);//obj2被释放,但也不会释放刚才Load的Texture
Resources.UnloadUnusedAssets();//这时候刚才load的Texture
Asset释放了,因为没有任何引用了
GC.Collect(); // 强制立即释放内存
用AssetBundle加载的asset一样可以用Resources.UnloadUnusedAssets卸载,但必须先AssetBundle.Unload,才会被识别为无用的asset
4. 场景切换
自动销毁:
a.
所有的内存对象都会被自动销毁,包括你用AssetBundle.Load加载的对象和Instaniate克隆的。
b. Unity在一个场景开始时,根据场景构成和引用关系所自动读取的资源,只有在读取一个新的场景或者reset当前场景时,才会得到清理。
不自动销毁:
a.
AssetBundle文件自身的内存镜像,那个必须要用Unload来释放,用.net的术语,这种数据缓存是非托管的。
b. 在场景之间被保持的脚本(通常这些脚本所挂载的GameObject,作为了DontDestroyOnLoad函数的参数,即被其标识为场景切换时不失效),且这些脚本很可能含有对其他物体的Component或者资源的引用,这些资源就都得不到释放。
c. static的单例(singleton)在场景切换时也不会被摧毁,如果这种单例含有大量的对资源的引用,也会成为大问题。
5. a. Load的是Asset,
销毁时:Load的Asset要Unload
b. Instantiate的是GameObject和Object
in Scene,销毁时: Instantiate的或者new的object可以Destroy
c. Texture加载以后是到内存,显示的时候才进入显存的Texture
Memory
总结:
三种加载方式的区别:
静态引用 + Resouces.load()
引用对象texture是在instantiate时加载, 第一次instantiate时会包含加载引用
assets的操作,导致第一次加载的延迟
assetBundle.Load()
会把perfab的全部assets 都加载,instantiate时只是生成Clone
a. Destroy: 主要用于销毁克隆对象,也可以用于场景内的静态物体,不会自动释放该对象的所有引用。虽然也可以用于Asset,但是概念不一样要小心,如果用于销毁从文
件加载的Asset对象会销毁相应的资源文件!但是如果销毁的Asset是Copy的或者用脚本动态生成的,只会销毁内存对象。
你Load出来的Assets其实就是个数据源,用于生成新对象或者被引用,生成的过程可能是复制(clone)也可能是引用(指针)
当你Destroy一个实例时,只是释放那些Clone(复制)对象,并不会释放引用对象和Clone的数据源对象,Destroy并不知道是否还有别的object在引用那些对象。
等到没有任何 游戏场景物体在用这些Assets以后,这些assets就成了没有引用的游离数据块了,是UnusedAssets了,这时候就可以通过 Resources.UnloadUnusedAssets来释放。
b. AssetBundle.Unload(false):释放AssetBundle文件内存镜像
c. AssetBundle.Unload(true):释放AssetBundle文件内存镜像同时销毁所有已经Load的Assets内存对象
d. Reources.UnloadAsset(Object):显式的释放已加载的Asset对象,只能卸载磁盘文件加载的Asset对象
e. Resources.UnloadUnusedAssets:用于释放所有没有引用的Asset对象
f. GC.Collect()强制垃圾收集器立即释放内存
转摘自 http://blog.sina.com.cn/s/blog_74c22b2101019u9c.html
相关文章推荐
- JavaEE细节问题02——加载资源文件的三种方式
- 反射第六步 : 通过反射加载资源文件 三种方式
- 加载资源文件的三种方式
- WebView 加载资源的三种方式 一般使用第二种方式与H5交互
- 简述java加载资源文件的三种方式
- 输入流加载资源的三种方式
- Tocat加载资源的三种方式
- 【Android】三种加载布局资源的方式
- UE4:四种加载资源的方式
- SpringMVC访问静态资源的三种方式
- javaWeb-web项目中加载资源文件路径的两种方式
- ServletContext对象读取资源路径的三种方式
- Android获得图片资源的三种方式
- Android 三种方式实现自定义圆形页面加载中效果的进度条
- Spring的ApplicationContext加载多个配置文件的三种方式
- java加载配置文件的三种方式
- Android三种基本的加载网络图片方式
- UIWebView的三种加载方式
- 网站后端_Python+Flask.0004.FLASK配置管理之三种方式加载外部配置?
- Android三种基本的加载网络图片方式