1. Texture,都去掉alpha通道,作为背景展示的图片,基本都没有透明要求,有特殊要求的则放到atlas里面
a. Loading图这类需要比较精细的,则把图片设置为Automatic TrueColor,设置真彩色,保证不失真
b. 地图、缩略图、UI背景图等等要求不精细的,则可以设置为自动压缩格式(有压缩情况,都需要图片宽高尺寸是2的幂,可以在Advance里面设置toNearest)
 
注意:ios下会自动把图片宽高拉伸为2的幂次方尺寸,这样会导致图片显示失真,解决办法是制作图片的时候就保证是2的幂大小。如果图片显示的区域确实不能做出2的幂大小,可以用补黑边的方式把图片做出2的幂大小,设置图片的时候,就需要调整图片的UV
要点:android下,带alpha通道的图片,自动压缩是以ETC2 8bit的方式压缩的,不带alpha通道,是压缩成ETC 4bit的格式(ETC2 支持alpha通道),ios下是压缩成PVRTC 4格式。手机硬件对各种格式图片的加载效率不一样,RGBA32是最慢的。所以需要对图片进行处理,改压缩方式,ETC和pvr是加载最快的。
 
2. animation clip
动作片段的优化,主要是减少动作的无用帧,就是两个Keyframe之间的旋转或者位移或者缩放的差别很小很小,则可以把Keyframe去掉,这样一个几百k的动作片段优化下来可能只有几十k,还是相当可观的
 static List<Keyframe> TrimScaleKeyframes(AnimationClipCurveData curve)
{
List<Keyframe> keyframes = __keyframes;
float maxValue, minValue, averageValue;
keyframes.Clear();
List<KeyframeSample> samples = TakeSamples(curve, out maxValue, out minValue, out averageValue);
int depth = curve.propertyName.Split('/').Length;
var kcount = samples.Count;
keyframes.Add(samples[].keyframe);
bool lastIsRemoved = false;
Keyframe lastKeyframe = new Keyframe();
var epsilon = m_scaleError;
float error = ;
for (int k = ; k < kcount - ; ++k)
{
var kf = samples[k].keyframe;
var diff = samples[k].pos.y - keyframes[keyframes.Count - ].value;
error += diff;
if (Mathf.Abs(error) > epsilon)
{
if (lastIsRemoved)
{
keyframes.Add(lastKeyframe);
lastIsRemoved = false;
}
keyframes.Add(kf);
error = ;
}
else
{
lastIsRemoved = true;
lastKeyframe = kf;
}
}
keyframes.Add(samples[kcount - ].keyframe);
if (keyframes.Count == )
{
if (Math.Abs(keyframes[].value - keyframes[].value) < Mathf.Abs(m_positionError))
{
keyframes[] = KeyframeUtil.GetNew(keyframes[].time, keyframes[].value, TangentMode.Linear, TangentMode.Linear);
keyframes[] = KeyframeUtil.GetNew(keyframes[].time, keyframes[].value, TangentMode.Linear, TangentMode.Linear);
}
}
return keyframes;
}
 
3. 检查无效的脚本
很多时候美术制作资源的时候,为了即时看到效果,会把脚本给挂上去,但是制作完以后通常会忘了把脚本卸载。通常这些资源会打包成bundle资源,这个时候脚本就会缺失,加载bundle的时候会一直报警告消息,这样会增加CPU的开销,严重的话会引起卡顿。所以检查无效的脚本是很有必要的。不过有哪些无效脚本,这个就需要统计了,是个体力活
 
4. 特效的检查
游戏里面的特效非常多,几百上千个。而特效里面引用相同材质的情况是很多的,如果不把这些材质的剔出来,会造成很多资源的冗余。一个最简单的办法就是把所有特效的材质贴图都抠出来打包成一个bundle文件,加载特效的时候动态加载材质贴图,还是会减少几MB内存的。
还有一点,特效贴图很多都使用了alpha通道,渲染的时候容易造成重绘情况(alpha test和alpha blend),会加大CPU和开销。解决办法是拆分贴图的alpha,shader里面做alhpa的混合。这样会时游戏更加流畅一点,就是实现起来稍微麻烦一些
 
5. 场景处理
纹理合并+静态批处理,lightmap贴图设置自动压缩。一个是减少drawcall,一个是减少内存占用。静态批处理的
 
6. atlas贴图
和特效贴图类似,也是拆分alpha通道,在shader里面做混合。不过有一个很大的好处就是,atlas都是需要显示很精细的,做贴图压缩处理的时候基本都是使用true color,一个1024x1024的 RGBA32的图片在内存中会占用4MB的大小。做了alpha通道拆分后,就可以把alpha图片和RGB图片做自动压缩成ETC 4bit格式,占用的内存会大大减少。对于游戏同时会使用几个atlas的情况下,这种处理方式一个atlas大概就能减少2到3MB的内存,几个下来,20MB都有可能,还是很客观的
 
7. GameUI 游戏窗体界面
窗体界面在打包的时候把挂载的脚本去掉,加载窗体的时候动态挂上去。还有一点,打包的时候处理资源的依赖关系是很麻烦的,所以一劳永逸的办法是,把窗体引用的atlas和font都去掉,在加载窗体的时候再动态挂回来,有点像脚本的处理方式,只是代码实现上稍微复杂点,还是很简单的。这样也不用担心窗体打包成bundle后过大的问题。200个窗体,通过这样打包bundle,总共5MB左右,atlas和font单独打包成bundle。还有一点,有些项目是把atlas、font、UI打包成一个bundle资源,这样也可以解决重复依赖的问题。但是这样会增加内存开销,毕竟所有atlas、font、UI都一次性加载完了。所以一个文件打成一个bundle,在加载的时候可以使内存过度比较平缓。
 
8. 角色模型和怪物模型处理依赖
角色模型通常都会有几套动作,所以打包角色模型时都需要先把角色上的动作给去除掉,游戏中在动态挂上去。这样处理需要动作文件命名规范,有可能会用到配置表。
怪物、npc、坐骑等模型和动作基本都是一一对应的,不存在冗余的情况,所以不用拆分动作,直接全依赖打包
 
9. 音效、texutre不需要考虑依赖情况,直接打包。不过,因为这类资源本身都是经过压缩的,打包的时候可以尝试选择不压缩打包的方式打成bundle,加载bundle的时候就是加载的没有压缩的资源,可以提高加载资源的速度
 
10. 场景打包,unity 5.0以后加入了LZ4的压缩方式,对比LZMA的压缩方式,在加载速度上提升是非常大的,我测试过加载场景,使用LZMA的bundle同步加载时间是0.8s,使用LZ4的bundle加载的时间只有0.005s,快赶上不压缩的方式了。一个场景文件通过LZMA压缩后的大小是10MB, LZ4的大小是15MB,不压缩的大小就是25MB。所以个人推荐还是使用LZ4的方式打包场景,不过也不是所有的场景都需要用LZ4,毕竟还是大了有大概0.3倍的大小。所以可以把游戏的前面几张场景使用LZ4打包,后面的用LZMA。这样,玩家开始玩的时候还是能有不错体验的。最终怎么取舍还是看项目具体的需求吧
如果资源采用不压缩的方式打包,然后再对总资源进行zip压缩,包体最终是小了,不过提交到ios后台看到的包体大小却是zip解压后的大小。目测ios后台是会自动识别zip压缩的。一个办法是自己写压缩算法,个人觉得还是比较麻烦。在手机硬件提升越来越快的情况下,没有必要为了低端机做不压缩的处理。中高端机对于不压缩的资源加载和LZ4的资源加载,几乎无感,孰高孰低,仁者见仁吧

Unity 打包总结和资源的优化和处理的更多相关文章

  1. Unity打包/读取AssetBundle资源全教程

    Unity 资源AssetBundle打包 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar ...

  2. unity 打包资源及网络请求资源包

    第一步 导包 在Assets新建一个Editor目录 新建一个Test类 using UnityEngine; using System.Collections; using UnityEditor; ...

  3. Unity打包同一文件Hash不一样

    问题起因 游戏开发基本都会涉及到资源版本管理及更新,本文记录我在打包过程中遇到的一小问题: 开过中常用于标记资源版本的方法有计算文件Hash.VCS的版本等. 在Unity中对同一个资源文件进行多次打 ...

  4. Unity Awards 2018最佳资源

    好的工具与资源,将帮助你的开发,达到事办功倍,今天我们将为大家介绍荣获Unity Awards 2018最佳资源的获奖作品. 最佳艺术工具:Aura - Volumetric Lighting Aur ...

  5. 实力封装:Unity打包AssetBundle(大结局)

    →→前情提要:让用户选择要打包的文件←← 大结局:更多选择 Unity打包AssetBundle从入门到放弃系列终于要迎来大结局了[小哥哥表示实在写不动了o(╥﹏╥)o]... 经过上一次的教程,其实 ...

  6. Unity开发实战探讨-资源的加载释放最佳策略简要心得

    Unity开发实战探讨-资源的加载释放最佳策略简要心得 看过我另外一篇关于Unity资源释放随笔<Unity开发实战探讨-资源的加载释放最佳策略>如果觉得略微复杂,那么下面是一些比较简要的 ...

  7. Unity开发实战探讨-资源的加载释放最佳策略

    注:本文中用到的大部分术语和函数都是Unity中比较基本的概念,所以本文只是直接引用,不再详细解释各种概念的具体内容,若要深入了解,请查阅相关资料. Unity的资源陷阱 游戏资源的加载和释放导致的内 ...

  8. 使用webpack打包ThinkPHP的资源文件

    使用webpack打包ThinkPHP的资源文件 利用自己的空余时间一直在维护http://www.wx2share.com这个小网站,全是一个人在弄,由于只租得起虚拟空间,所以后台采用了简单方便的T ...

  9. UNITY 打包安卓APK

    1,安装JDK.这个直接下就行了. 2,安装android sdk相关.这个比较蛋疼,官网是被墙的.有些网站的包还是需要访问墙外下载的.关键是找对那个能用的包(对我来说就是不FQ). http://p ...

随机推荐

  1. java构造代码块,构造函数和普通函数的区别和调用时间

    在这里我们谈论一下构造代码块,构造函数和普通函数的区别和调用时间.构造代码块:最早运行,比构造函数运行的时间好要提前,和构造函数一样,只在对象初始化的时候运行.构造函数:运行时间比构造代码块时间晚,也 ...

  2. Swift try try! try?使用和区别

    Swift try try! try?使用和区别 一.异常处理try catch的使用 1. swift异常处理 历史由来 Swift1.0版本 Cocoa Touch 的 NSError ,Swif ...

  3. Java中四种遍历List的方法

    package com.ietree.basic.collection.loop; import java.util.ArrayList; import java.util.Iterator; imp ...

  4. 厉害了我的雅虎!卖掉主业后更名为阿里他爸(Altaba)

    据雅虎周一向美国证券交易委员会(SEC)提交的文件显示,在美国通信巨头Verizon斥资48亿美元收购雅虎的交易完成后,该公司首席执行官玛丽莎o梅耶尔(Marissa Mayer)将退出公司董事会. ...

  5. jQuery常用代码片段

    检测IE浏览器 在进行CSS设计时,IE浏览器对开发者及设计师而言无疑是个麻烦.尽管IE6的黑暗时代已经过去,IE浏览器家族的人气亦在不断下滑,但我们仍然有必要对其进行检测.当然,以下片段亦可用于检测 ...

  6. Java并发包分析——BlockingQueue

    之前因为找实习的缘故,博客1个多月没有写了.找实习的经历总算告一段落,现在重新更新博客,这次的内容是分析Java并发包中的阻塞队列 关于阻塞队列,我之前是一直充满好奇,很好奇这个阻塞是怎么实现.现在我 ...

  7. LeetCode4. Median of Two Sorted Arrays---vector实现O(log(m+n)--- findkth

    这道题目和PAT上的1029是同一题.但是PAT1029用O(m+n)的时间复杂度(题解)就可以,这道题要求是O(log(m+n)). 这道题花费了我一个工作日的时间来思考.因为是log因而一直思考如 ...

  8. hdu3586 Information Disturbing 树形DP+二分

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3586 题目大意:给定n个敌方据点,编号1为司令部,其他点各有一条边相连构成一棵树,每条边都有一个权值c ...

  9. flume集群日志收集

    一.Flume简介 Flume是一个分布式的.高可用的海量日志收集.聚合和传输日志收集系统,支持在日志系统中定制各类数据发送方(如:Kafka,HDFS等),便于收集数据.其核心为agent,agen ...

  10. Spring AOP的切入点表达式

    在spring Aop中要使用AspectJ的切点表达式语言来定义切点.Spring仅仅支持AspectJ切点指示器的一个子集.下表列出了Spring AOP所支持的AspectJ切点指示器. 在Sp ...