这个错可能是证书或签名出问题了。
作者存档: 朱坤乾 - 第8页
fmod ERR_HTTP_PROXY_AUTH
FMOD Error (ERR_HTTP_PROXY_AUTH): Proxy authentication is required to access the specified resource. UnityEngine.Debug:LogWarning(Object) FMOD.Studio.UnityUtil:LogWarning(String) (at Assets/Plugins/FMOD/FMOD_StudioSystem.cs:53) FMOD.Studio.UnityUtil:ERRCHECK(RESULT) (at Assets/Plugins/FMOD/FMOD_StudioSystem.cs:120) FMOD_StudioSystem:ERRCHECK(RESULT) (at Assets/Plugins/FMOD/FMOD_StudioSystem.cs:401) FMOD_StudioSystem:Init() (at Assets/Plugins/FMOD/FMOD_StudioSystem.cs:274) FMOD_StudioSystem:get_instance() (at Assets/Plugins/FMOD/FMOD_StudioSystem.cs:153) TestLoading:Awake() (at Assets/scripts/config_model/TestLoading.cs:47)
这个错误之前遇到过一次。
这次遇到后忘记如何解决的了,白白费了半天工夫。这里记录下,免得自己又忘记了。
解决方式也很傻瓜式,把fmod的script及so,dll重新导入了一遍。
unity中的streaming文件路径
IEnumerator test1(){ String filePath1=Application.streamingAssetsPath+"/Boss.bank"; String filePath2="file:///"+Application.streamingAssetsPath+"/Boss.bank"; String filePath3=System.IO.Path.Combine(Application.streamingAssetsPath,"/Boss.bank"); String filePath4=System.IO.Path.Combine(Application.streamingAssetsPath,"Boss.bank"); textbox1.label.text=filePath1+"\n\n"+filePath2+"\n\n"+filePath3+"\n\n"+filePath4+"\n\n"; textbox1.label.text+=File.Exists(filePath1)+"\n"; textbox1.label.text+=File.Exists(filePath2)+"\n"; textbox1.label.text+=File.Exists(filePath3)+"\n"; textbox1.label.text+=File.Exists(filePath4)+"\n"; WWW www1=new WWW(filePath1); yield return www1; WWW www2=new WWW(filePath2); yield return www2; WWW www3=new WWW(filePath3); yield return www3; WWW www4=new WWW(filePath4); yield return www4; textbox1.label.text+=www1.bytesDownloaded+" "+www1.error+"\n"; textbox1.label.text+=www2.bytesDownloaded+" "+www2.error+"\n"; textbox1.label.text+=www3.bytesDownloaded+" "+www3.error+"\n"; textbox1.label.text+=www4.bytesDownloaded+" "+www4.error+"\n"; }
PC 运行如图:
android手机运行如图:
如果在unity中取文件:
string filePath = System.IO.Path.Combine(Application.streamingAssetsPath, "csv/"+configName); byte[] result=null; if (filePath.Contains("://")) { WWW www = new WWW(filePath); yield return www; while(!www.isDone()){ yield return null; } result = www.bytes; } else { result = System.IO.File.ReadAllBytes(filePath); }
如果在unity中想全部用www取文件
string filePath3 = Application.streamingAssetsPath + "/bt2/android/"; if (!filePath3.Contains("://")) { filePath3 = "file:///" + filePath3; }
在android下需要注意,因为apk本身是压缩格式,无法直接用File取文件,必须用www取文件。
用www取文件注意格式,一定要等www.isDone
今天查找unity中加载配置表卡的问题(二)
接上一重篇:
上次修改完成后,配置加载已经非常快了, 但发现了另外一个现象,在检查配置更新时会卡上约6秒左右。
检查更新做的事情很简单,就是去网上请求一个静态文件,这里为什么卡成这样。
添加了一些埋点代码记录运行的时间后发现,卡在了加载音频那里,游戏中的音频有30M,而且那里是同步加载 -.-!! ,现在需要对音频进行拆分,
1、一部分需要在登陆前加载,比如UI上绑定的音频之类(按钮声)
2、一部分需要在战斗前加载成功,比如战斗中的音频
3、一部分需要异步加载,比如背景音乐之类
4、一部分只需要用时再加载,用完立即释放掉,比如人物对话音频之类。
另外在splash image后第一个场景需要update执行完后才会显示出来,因此有些非常耗时的操作避免在第一次update时执行。
图片格式压缩
记录,避免自己忘记
1、http://bellard.org/bpg/ bgp压缩格式。
2、https://github.com/nagadomi/waifu2x 相关文章:http://blog.codingnow.com/2015/05/rgbyuv.html#more 卡通图片压缩格式
3、WebP google家的图片压缩算法,facebook也在使用。(注:cpu密集型,不适合游戏)
4、云风的ejoy2d使用的 ppm 和 pgm 格式。
韦一笑:
同信噪比情况下,图片尺寸: Jpeg > JPEG2000 > webp > hdphoto > BPG Webp:使用 vp8 I帧编码 hdphoto:微软自己私有格式,扩展名为wdp bpg:H.265 的I帧编码算法,应该是目前压缩效果最好的格式,具体对比见Fabrice 的个人主页:http://bellard.org/ 新格式一直都有,只是应用滞后了而已。比如google开源webp,挺好的,微软就是不买账,不支持。fabrice比较聪明,直接给他的bpg写了两套解码库:C的和javascript的,于是浏览器支持问题被解决了,只是各个网站跟进慢了而已。
bpg更好,png8 存alpha bpg存rgb,载入时自动生成并缓存成pvr,很多快速生成pvr的算法,webp弱爆了 游戏包里放bpg,然后弄一个pvr cache,读取时先找cache,没有就从bpg里转一份出来放倒cache中,只有一次转码,你担心啥呢,何况每次下载更新时边下边转,基本感觉不到
想起来了以前听过一次,说是如果将是全透或全不透,是否可以将alpha信息存在颜色信息的最后一位上。没有试过。可以测试下看看效果如何。
linux下两个好用的图像转换工具(自己造轮子太笨重了): ImageMagick和convert。
几个压缩图片的工具,图片会轻微失真,UI不建议用
https://tinypng.com/
https://tinyjpg.com/
http://www.gimp.org/
https://pngquant.org/
协议压缩:
1、https://code.google.com/p/snappy/ 可以考虑下这个。另外如果想要最优,可以考虑比较下各种压缩算法在实际项目中使用的效果。
注:如果游戏中对其它文件使用了压缩算法,需要专门测试一下以下几个方面
1、是否为系统原生提供,是否为第三方库方式提供。(c#如果有原生库速度会更快)
2、各种算法比较,主要比较的是速度和压缩比。如果是第三库可以考虑将crc32校验都去除。
3、是否有条件使用c/c++编译为so提供给mono使用。
又一篇关于压缩的文章:
https://zhuanlan.zhihu.com/p/21543787
今天查找unity中加载配置表卡的问题
我们游戏中第一次运行中,会下载配置表并进行加载。
但是我们发现一个现象:
第一次下载后,会在加载那里卡5秒左右。而以后再也不会遇到相同的卡的状况。
花了些时间发现了原因是c#代码导致的。
我们配置表使用csv,第一次下载后通过www类可以拿到下载的byte[],想避免一次IO操作,就使用c#写了解析为字符串数组的代码。
而非第一次下载,则使用File.ReadAllLine直接从文件中读取。
原来写时,以为能避免一次IO操作,可以提高性能,这里不能不说,C#自带的函数(底层使用c/c++实现),要远比c#的代码速度快的多。
也有可能是我写的C#代码太烂了的原因。
烂代码大家可以了解下:就是被注释掉的代码引导的卡。
string[] allDatas = null; /* if (doneList != null) { for (int m = 0; m < doneList.Count; m++) { ConfigFile cf = doneList[m]; if (cf.configName.Equals(configName+".bin")) { Debug.Log("Time1 :"+Time.realtimeSinceStartup); StringReader sr = new StringReader(UTF8Encoding.UTF8.GetString(cf.content)); List<string> list = new List<string>(); string str = null; while ((str = sr.ReadLine()) != null) { list.Add(str); } Debug.Log("Time2:"+Time.realtimeSinceStartup); allDatas = list.ToArray(); Debug.Log("Time3:"+Time.realtimeSinceStartup+" "+configName+" "+list.Count); break; } } } */ if (allDatas == null) { string path = PathMgr.Config_Path + configName + ".bin"; allDatas = File.ReadAllLines(path); }
游戏中数据包的压缩
我们游戏中数据包比较大时,就使用7z进行压缩后,再传给客户端。
最近压力测试时,发现一个坑,查了几天,才定位是使用的7z库的问题。
java中没有官方的7z库,也没有开源组织维护,只有一个作者自己写的7z库,最初没发现问题。
这次查看7z的源码,发现里面每次压缩时会分配16M内存,大量的分配释放内存导致整个jvm都被卡了。
没办法改为gzip库,来避免掉了这种问题。
关于压缩实际还有很多潜力可以挖掘。
1、比如:压缩解压每个数据块中有crc32校验,我们游戏中使用,可以直接去掉这部分计算。
2、比如:既然不使用crc32校验证,那crc32占用的那几个字节就可以省掉。
3、比如:既然前后端都知道使用相同的压缩算法,就可以把压缩文件的格式文件头去掉。
4、比如:每次压缩解压都会申请byte[],我们可以使用threadlocal复用byte[],来减少byte[]的分配。
protobuf使用遇到一个坑
项目压力测试,发现一个协议非常卡,吞吐量不足100/s,查看那个协议,发现是在玩家登陆成功后取玩家数据。
这个protobuf结构体 A 中定义了接近300个属性。
专门测试了一下,生成100000个对象,属性全不设置使用默认值,A结构体序列化是仅有几个属性的40倍消耗。
这个地方是我们之前没有想到的情况,不过这还不足已是瓶项的原因。
再继续确认,发现A里面有一个list,list中存放了271个B结构体。大约40%的时间都消耗在这里了。
基本上以下是我们之前未发现的:
1、protobuf属性多了会导致性能下载,既然属性值使用optional,而且不设置值。属性尽量控制在比较少的范围内。
2、属性多了后,感觉性能消耗是几何数级增加。
针对我们项目目前的情况,A结构体进行拆分不太可能,所以只把其中几个数量多的list拆分出来。把上面的271个使用另外一个协议发送,每次发送一条,总共发送271条。可能会感觉271条协议比一个协议要慢,实际上发现,这样做了后,问题顺利解决,271条比1条消耗的时间要小2个数量级,可能protobuf天生只适合小数据包的情况。
记一次排查内存泄露
今天一台java帐号服上报了outofmemory,这种错误出现,大多数情况都是有内存泄露导致的。
看程序运行目录下自动生成了 java_pid32123.hprof 文件。这是java自动dump出来的文件,里面记录了内存不足时的内存信息。
可以用jhat打开hprof文件。
耗时会比较长,耐心等待。
上面的7000,是指打开了一个http 7000端口,我们可以通过浏览器进行查看。
通过浏览器打开后,拉到最后面:
点击show instance counts for all classes
看到最上面几行,基本上就可以确认了SocketRunner出现了内存泄露。
生成了大量socketrunner,导致无法及时处理,最终耗尽了所有内存。
svn批量处理
批量添加文件至svn
svn status | awk '{if($1 == "?"){print $2}}' | xargs svn add svn commit
批量解决 : Node remains in conflict
svn resolve --accept theirs-full . svn update | awk '{if($1 == "Skipped"){print $2}}' | xargs svn resolved svn update svn resolve --accept theirs-full .
批量提交已经删除的文件
svn status | awk '{if($1 == "!"){print $2}}' | xargs svn rm
近期评论