Unity3D内存优化案例讲解
来源:互联网 发布:没有激素的护肤品知乎 编辑:程序博客网 时间:2024/05/20 18:53
笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。
CSDN视频网址:http://edu.csdn.net/lecturer/144
游戏开发中涉及到内存优化方面的问题:一是美术方面的问题,二是程序代码的问题。主要是给读者说说程序的问题,以下面代码为例进行讲解。下面这段代码相信读者在程序中经常会这样写,代码存在很多问题,下面就给读者一一道来。
while (currentPreviewNumber < 12) { Debug.Log (currentPreviewNumber); byte[] tBytes = System.IO.File.ReadAllBytes (Application.persistentDataPath + "/" + currentPreviewNumber + ".jpg"); Texture2D texture = new Texture2D (100, 100); texture.LoadImage (tBytes); sprites [currentPreviewNumber] = Sprite.Create (texture, new Rect (0, 0, mCamera.width, mCamera.height), new Vector2 (0.5f, 0.5f), 40); currentPreviewNumber++; }
有人可能会说,直接使用GC.Collection(),其实情况并不是你想的那样,我们完全可以对代码进行优化,以减少内存分配。主要从以下几点去优化:
1、这些内存分配大部分是Sprite.Create。 它分配内存不好, 解决方案是改变这样的设计, 使用RawImage数组而不是Sprite数组,这种不必要的内存分配将会消失。
2、Texture2D texture = new Texture2D(100,100); 也会分配内存, 由于它始终是100乘100,您可以重新申请它, 使其成为全局,并调用新的Texture2D(100,100); 仅调用一次,在Start函数中, 这极大的节省了内存分配。
3、利用StringBuilder把Application.persistentDataPath + "/" + currentPreviewNumber + ".jpg"串联起来。
4、Application.persistentDataPath 分配内存 将其存储在Start()函数中的临时值中,而不是在while循环中重复调用它。
解决方案一:
public RawImage defaultRawImage;RawImage[] rawImages;Texture2D texture = null;int currentPreviewNumber = 0;string appPath;System.Text.StringBuilder imagePath;void Start(){ appPath = Application.persistentDataPath; //Init Texture 2D texture = new Texture2D(100, 100, TextureFormat.RGB24, false); //Init All 12 Raw Images rawImages = new RawImage[12]; for (int i = 0; i < rawImages.Length; i++) { rawImages[i] = Instantiate(defaultRawImage) as RawImage; } //Init String Builder imagePath = new System.Text.StringBuilder(300);}void loadPreviewOptimized(){ while (currentPreviewNumber < 12) { //Debug.Log(currentPreviewNumber); imagePath.Capacity = 0; imagePath.Append(appPath).Append("/").Append(currentPreviewNumber).Append(".jpg"); //Read File byte[] tBytes = System.IO.File.ReadAllBytes(imagePath.ToString()); texture.LoadImage(tBytes); rawImages[currentPreviewNumber].texture = texture; currentPreviewNumber++; }}
byte [] tBytes = System.IO.File.ReadAllBytes(imagePath.ToString()); 代码分配内存来返回字节。 为了摆脱它,使tBytes成为一个全局变量,然后分配内存一次。 当您想通过File.ReadAllBytes停止内存分配时,下面是完整的代码。
解决方案二:
public RawImage defaultRawImage;RawImage[] rawImages;Texture2D texture = null;int currentPreviewNumber = 0;string appPath;System.Text.StringBuilder imagePath;byte[] tBytes;void Start(){ appPath = Application.persistentDataPath; //Init Texture 2D texture = new Texture2D(100, 100, TextureFormat.RGB24, false); //Init All 12 Raw Images rawImages = new RawImage[12]; for (int i = 0; i < rawImages.Length; i++) { rawImages[i] = Instantiate(defaultRawImage) as RawImage; } //Init String Builder imagePath = new System.Text.StringBuilder(300); tBytes = new byte[90000];}void loadPreviewOptimized(){ while (currentPreviewNumber < 12) { //Debug.Log(currentPreviewNumber); //Reset Capacity before Reading imagePath.Capacity = 0; imagePath.Append(appPath).Append("/").Append(currentPreviewNumber).Append(".jpg"); //Read File using (System.IO.FileStream myfile = System.IO.File.Open(imagePath.ToString(), System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite)) { //Check if array size is enough before writing if (tBytes.Length >= myfile.Length) { //OK (Write file to tBytes array) myfile.Read(tBytes, 0, (int)myfile.Length); texture.LoadImage(tBytes); } else { //NOT OK (Resize array size) tBytes = new byte[myfile.Length]; //Write file to tBytes array myfile.Read(tBytes, 0, (int)myfile.Length); texture.LoadImage(tBytes); } rawImages[currentPreviewNumber].texture = texture; currentPreviewNumber++; } }}现在分配的内存是10.0kb,这很好。 如果要更好地优化,而不是在while循环中使用StringBuilder生成字符串,而是在Start函数中执行一次,
并将这些字符串路径存储到可以在while循环中稍后使用索引的字符串数组。
以上主要是给读者介绍了关于如何优化代码,希望有所帮助。。。。。
- Unity3D内存优化案例讲解
- Unity3D:内存优化
- Unity3d 如何优化内存
- Unity3d 内存优化:
- Unity3D移动平台内存优化
- Unity3D移动平台内存优化
- Unity3d内存管理与优化
- Unity3D移动平台内存优化
- Unity3D移动平台内存优化
- SQLServer Stolen内存优化案例
- Impala内存优化实战案例
- Impala内存优化实战案例
- PostgreSQL性能优化综合案例讲解 - 1
- PostgreSQL性能优化综合案例讲解 - 1
- PostgreSQL性能优化综合案例讲解 - 2
- unity3d内存优化的一些总结
- Unity3D 内存优化(一)对象池
- Unity3D 优化 5 (AssetBundle的SerializedFile内存)
- Round 6 B
- session和cookie理解
- 杭电acm 4540威威猫系列故事——打地鼠
- oracle数据库数据的同步操作
- 《图解 HTTP》读书笔记(一)
- Unity3D内存优化案例讲解
- 转载方法
- 初学opencv/特征匹配
- [LeetCode P4] Median of Two Sorted Arrays 解法
- poj2891
- xml解析
- 前端路由与后端路由
- CentOS6 安装并破解Jira 7
- Lua 脚本 Lua 脚本功能是 Reids 2.6 版本的最大亮点, 通过内嵌对 Lua 环境的支持, Redis 解决了长久以来不能高效地处理 CAS (check-and-set)命令的缺点,