??xml version="1.0" encoding="utf-8" standalone="yes"?> Unity?018版中加入了ECSpȝQ?但处于小白鼠阶段。默认不是Unity的一部分Q?需要手动下载代码ƈ导入PackagesQ新Ҏ(gu))。官Ҏ(gu)供v豚例子, 但除此之外例子和资料非常。所以完全无法,也不敢在demo中N然引入这U系l,所以放弃官方ECSpȝ?/p> W三方的EntitasQ?span style="border-bottom: 1px dashed gray;">https://github.com/sschmid/Entitas-CSharpQECS框架?015q就开始在各地演讲中介l。整体框架基于代码生成, 能解决一部分的代码爆炔R题, 而且性能也要好一些。例子,介绍非常丰富Q例子虽然基于不同版本的EntitasQ特性支持和最新版差不太多Q?只是写法有细微差异, 对于理解来说无碍?/p> l过1~2天的攚w, l于demo从传lUnity写法攚wؓ(f)ECS标准写法Q新增了46个文Ӟ 而传l逻辑一共只?6个文Ӟ大概Ҏ(gu)下ECS的特点和差异?/p> Entitas的ECSpȝ 1. 本来在一个对象中d一个类字段的过E,ECS需要添加一个类代表ComponentQƈ且代码生成?/p> q个字段一般用于描q对象的资源Q处理显C的GameObjectQ?表示对象的类型等?/p> 2. 本来一个对象的业务逻辑处理q程直接用方法解决的Q?ECS需要新加一个SystemQ而操作对象需要用Filter或Group查询获得?/p> 3. 一pd的操作, 需要拆分ؓ(f)多个System和Component拆分处理。如果System序不对Q??x)造成一些诡异的bug?/p> 4. Component不仅仅是Model承蝲体, 也可以是参数的数据结构。参数Component通过Entity传递到System处理?例如Q?通过ECS创徏一个方块的q程Q用CreateTileComponentQ包含创建Tile的位|, 创徏Entityq添加CreateTileComponentQ?在CreateTileSystem中处理就创徏了TileQ处理完成时Q?需要将传入的Entity.Destroy掉?/p> 6. Entity上修改Component的过E, ?x)触发事件。修改的q程需要用RelaceXXXQXXX表示lg名。组件可以频J修改, 不用担心d和删除组件过E的性能Q?Entitas底层处理性能只相当于指针赋值的性能?/p> ECS像什么? 1. ECS中的SystemcM触发器系l(Event-Condition-ActionQ,其中QEvent对应Entitas的GetTrigger+CollectorQ表C发事件。Condition对应Filter表示在事件来源对象中扑ֈ需要的对象?Action对应ExecuteQ表C实际的操作?/p> 2. ECS中的ComponentcM不用lua扩展的Redis或者不用存储过E的MySQLQ?Ua(b)U数据, 而不能对数据有Q何封装操作。没有lua和存储过E支持的db写v来还是比较费劲的Q但ECS是那么的纯?/p> 3. ECS中的Entity很尴,因ؓ(f)Component是按cdq箋存储的以保证性能?逻辑又需要Entityl合成逻辑需要的复合对象?两边都要照顾Q所以这U设计就让代码量巨增Q可L下降?/p> ECS企图用一套框架灭掉设计模?/span> 1. 单gQSingletonQ在Entitas用Unique标签标记ComponentQ?在Context中就是唯一的, 其实也就是Singleton?/p> 2. ECSq掉了传l的工厂模式Q底层统一对对象(EntityQ和属性(ComponentQ统一理。需要按Component中的值找回EntityӞ 可以使用EntityIndex?/p> 3. Entity携带不同的组件时Q整个创建和销毁过E被记录q恢复,其实是Command模式 ECS适合做UI框架Q类似MVVMQMVC,MVPQ么Q?/span> ECS不是专用的UI框架Q但是可以对不同pȝ和数据间解耦。传l代码中数据修改后的CallbackQECS也可以用Listener做, 但Listener因ؓ(f)能保存数据, 需要用Component保存?所以你需要面对的是,一个ButtonQ响应创Z个参数用的Component和SystemQ还要ؓ(f)数据改变写一套ListenComponent和Listener处理的SystemQ酸爽吧Q?/p> Minecraft适合ECS来做么? 可以Q性能应该能提升不,但是代码?x)更J琐Q特别像Javaq种啰嗦语言配上ECSq种啰嗦框架Q估计代码量ȝq是很轻杄。MC属于Ҏ(gu)cd的游戏,适合Ҏ(gu)领域特别优化Q也是专门为方块做出特别的设计来做优化。ECS属于通用框架Q即便性能OKQ但是代码未必能有良好的可读性?/p> 体量的游戏适合用ECS来做么? 可以Q但不徏议。特别是只有几个人维护的工程QN然上ECSpȝQ会(x)让系l变的极为复杂。当然你?x)说Q如果开发到后期Q传l开发模式会(x)D代码?x)ؕQECS?x)好些吧。掌握ECS也不是一天两天的事情Q不熟?zhn)ECS的程序员设计出来的系l获得的优势可能q不如用传统设计Ҏ(gu)好呢?/p> 架构解决的是人的问题Q?人都有问题,用什么框枉没办法?/p> 到底什么项目适合用ECSQ?/span> 1. 大量的小个体不断的生成和销毁以?qing)显C,例如Q?d战中Q要体现每个角色的移动,战斗?/p> 2. 多于5个h~写核心战斗逻辑。互相协作和模块切分Q需要一个大安能信服的框架QECS可以选择?/p> P.S. 不要造ECS的轮子! 很多同学看了ECS基本原理Q在没有深入使用qQ何ECSpȝ旉上操刀造轮子。ECSpȝ实看v来简单。实际造下来你?x)发玎ͼ性能非常p糕以及(qing)不知道一些逻辑如何用ECS来解冟?/p> ȝQ?/span> 1. ECS实为性能而生Q没有ƈ发加持性能的ECS都是耍流氓,要快p快到极致?/p> 2. Unity中,ECSq发能扩展CPU的利用率Q但是GPU的性能依然q是DrawCall优化那一套,别期望ECS?x)颠覆UnityQ性能也不?x)快到飞P关键q是要看具体的项目和人?/p> 3. ECS是万能框Ӟ但不全能。传l架构和设计思想也不是一无是处,熟啥用啥Q怎么快怎么来! 无ȝq告链接Q请各位支持 《Go语言从入门到q阶实战Q视频教学版Q?徐L)【摘?书评 试读? 京东图书 解决Ҏ(gu): 在ParticleSystemlg上勾选SubEmitter, 不要问ؓ(f)什? 做就?/p> 相关官方链接 http://answers.unity3d.com/questions/218369/shuriken-particle-system-not-rendering-particles-w.html 天煞? 4.XE序无法讉K_子pȝ的参? 所以只能辛苦美术兄弟们?/p> 转蝲h?http://www.shnenglu.com/sunicdavy战魂筑 |上有很多翻译了Ҏ(gu)官方的搭建ipv6试|络环境的文? 例如: 无需路由器支持ipv6, 但猫(modem)必须要支持ipv6. 因ؓ(f)现在大多数都是光?br>以下截图是光猫管理端 L(fng)认mac ospȝ必须是osx 10.11以后的版本才可以打开NAT64 转蝲h?http://www.shnenglu.com/sunicdavy战魂筑 WWWcLw已l支持了IPV6, 无需处理, q里讲解使用C#原生Socket的处? 4.7.2?.4.3的当前版本在mono层ƈ未支持ipv6代码适配的核心函数getaddrinfo, 因此需要通过oc层做转换, 以下是代?br>q段代码getaddrinfo的地址转换成一个完整字W串, 格式? P.S. copyStrq种用法参考了http://www.codeinsect.net/blog/2016/05/26/unity-ipv6-socket-%E6%94%AF%E6%8C%81%EF%BC%8C%E5%B7%B2%E6%B5%8B%E8%AF%95%E9%80%9A%E8%BF%87/ 转蝲h?http://www.shnenglu.com/sunicdavy战魂筑 iosaddrinfo.mm iosaddrinfo.h 某h的解x?br>http://www.codeinsect.net/blog/2016/05/26/unity-ipv6-socket-%E6%94%AF%E6%8C%81%EF%BC%8C%E5%B7%B2%E6%B5%8B%E8%AF%95%E9%80%9A%E8%BF%87/ 在每个protoc-gen-lua生成的lua文g? 都有一?/p> 本n按照官方出的没问? 但是在ulua的目录里, L报protobuf找不到的错误. 前后Ҏ(gu)了下我生成的lua和ulua官方生成的代码里 发现居然他修改了地址改ؓ(f)?/p> 好吧, 只有修改生成器代码protoc-gen-lua\plugin\protoc-gen-lua中第412行改?/p> q个错误真是让我哭笑不得, protoc-gen-lua的可用性再一ơ被怀?/p>
我们的协议好歹分成了接近100? 每个里面消息和数据是混合? 更别说有些童鞋喜Ƣ把一个项目的协议全写在一个文仉, 那生成的local数量直是酸爽 后记 搜烦(ch)protoc-gen-lua? 无意间又搜到3q前自己的博?a title="http://www.shnenglu.com/sunicdavy/archive/2013/04/24/199693.html" href="http://www.shnenglu.com/sunicdavy/archive/2013/04/24/199693.html">http://www.shnenglu.com/sunicdavy/archive/2013/04/24/199693.html 记得那个时候准备在服务器用lua, q好没这么干, 转了go, 否则后果不堪设想 lua上用pb其实q不Ҏ(gu), 云风的pbc写的不错, 但怕有? sproto直接不兼容现有项? 风险大于易用性所以果断弃?/p>
因此, 看来有必要自己写一个支持良好的lua pb?/p>
]]>
]]>基本注意?/h3>
试|络环境搭徏
http://www.cocoachina.com/ios/20160525/16431.html
注意以下几点
光猫里的ipv6支持默认是关闭的, 所以需要手动打开, 按默认值配|即?/p> Unity3D的Socket适配
ipv4|ipv4地址|ipv6|ipv6地址|
?x)造成内存泄露, 如果有更好的Ҏ(gu)Ƣ迎反馈 1: #include <sys/socket.h>
2: #include <netdb.h>
3: #include <arpa/inet.h>
4: #include <err.h>
5: #define OUTSTR_SIZE 4096
6: extern "C"
7: {
8: const char* copyStr( const char* str )
9: {
10: char* s = (char*)malloc(strlen(str) + 1);
11: strcpy(s, str);
12: return s;
13: }
14: const char* IOSGetAddressInfo(const char *host )
15: {
16: if( NULL == host )
17: return copyStr("ERROR_HOSTNULL");
18: char outstr[OUTSTR_SIZE];
19: struct addrinfo hints, *res, *res0;
20: memset(&hints, 0, sizeof(hints));
21: hints.ai_family = PF_UNSPEC;
22: hints.ai_socktype = SOCK_STREAM;
23: hints.ai_flags = AI_DEFAULT;
24: printf("getaddrinfo: %s\n", host);
25: int error = getaddrinfo(host, "http", &hints, &res0);
26: if (error != 0 )
27: {
28: printf("getaddrinfo: %s\n", gai_strerror(error));
29: return copyStr("ERROR_GETADDR");
30: }
31: memset( outstr, 0, sizeof(char)*OUTSTR_SIZE );
32: struct sockaddr_in6* addr6;
33: struct sockaddr_in* addr;
34: const char* solvedaddr;
35: char ipbuf[32];
36: for (res = res0; res; res = res->ai_next)
37: {
38: if (res->ai_family == AF_INET6)
39: {
40: addr6 =( struct sockaddr_in6*)res->ai_addr;
41: solvedaddr = inet_ntop(AF_INET6, &addr6->sin6_addr, ipbuf, sizeof(ipbuf));
42: strcat ( outstr, "ipv6|");
43: strcat ( outstr, solvedaddr);
44: }
45: else
46: {
47: addr =( struct sockaddr_in*)res->ai_addr;
48: solvedaddr = inet_ntop(AF_INET, &addr->sin_addr, ipbuf, sizeof(ipbuf));
49: strcat ( outstr, "ipv4|");
50: strcat ( outstr, solvedaddr);
51: }
52: strcat ( outstr, "|");
53: }
54: return copyStr(outstr);
55: }
56: }
转蝲h?http://www.shnenglu.com/sunicdavy战魂筑
1: #pragma once
2: extern "C"{
3: const char* IOSGetAddressInfo(const char *host );
4: }
q回l定的host内多个IP地址, 可以供处理复杂的北网?南电(sh)信问?/li> 1: using System;
2: using System.Net;
3: using System.Net.Sockets;
4: using System.Runtime.InteropServices;
5: using UnityEngine;
6: using System.Collections;
7: using System.Collections.Generic;
8: public class IOSIPV6
9: {
10: [DllImport("__Internal")]
11: private static extern string IOSGetAddressInfo(string host );
12: public static IPAddress[] ResolveIOSAddress(string host, out AddressFamily af)
13: {
14: af = AddressFamily.InterNetwork;
15: var outstr = IOSGetAddressInfo(host);
16: Debug.Log("IOSGetAddressInfo: " + outstr);
17: if (outstr.StartsWith ("ERROR"))
18: {
19: return null;
20: }
21: var addressliststr = outstr.Split('|');
22: var addrlist = new List<IPAddress>();
23: foreach (string s in addressliststr)
24: {
25: if (String.IsNullOrEmpty(s.Trim()))
26: continue;
27: switch( s )
28: {
29: case "ipv6":
30: {
31: af = AddressFamily.InterNetworkV6;
32: }
33: break;
34: case "ipv4":
35: {
36: af = AddressFamily.InterNetwork;
37: }
38: break;
39: default:
40: {
41: addrlist.Add(IPAddress.Parse(s));
42: }
43: break;
44: }
45: }
46: return addrlist.ToArray();
47: }
48: }
转蝲h?http://www.shnenglu.com/sunicdavy战魂筑
参考链?/h3>
注意, 此方案中的方法可? 但是地址q不能解军_北互通的问题
生成好的协议报错找不到protobuf
local protobuf = require "protobuf"
local protobuf = require "protobuf/protobuf"
lua('local protobuf = require "protobuf/protobuf"\n')
生成消息无法扑ֈDescriptor反射查信?/h2>
在LuaFramework\ToLua\Lua\protobuf\protobuf.lua?39行添?/pre>
message_meta._member.Descriptor = descriptor
在消息里可以通过msg.Descriptor获得此消息的反射信息
׃proto文g定义的内容过多导致的lua local过限制的警?/h2>
1. 技能部分的Ҏ(gu)可以遍历动作表播攄所有特效id, 提前预蝲
2. buffcȝ效是动态确定的,无法分析. 需要通过角色表添加资源id在加载角色时加蝲Ҏ(gu)
q种做法的缺?
当角色特效效果调整时, 术和策划需要调整特效id? 多出来不用的Ҏ(gu)也加载是感觉不出来的, 分析也是很困隄
所以这U以传统的电(sh)子表格配|ؓ(f)中心的方式在Unity3D? 内存, 包优化会(x)是个大问?
那么, 什么是Unity3D的开发核心思想?
除了lg思想? 是Prefab, 贯彻整个~辑器及(qing)引擎自始至终
处理角色携带Ҏ(gu)加蝲后播攄q个case, 用PrefabZ心的资源理来做的话, 大概是q样:
1. E序~写一个角色特效列表脚? 把List暴露出来可以在编辑器里?/p>
2. 术在做技能时, 把要用到的特效拖拽到List?/p>
3. Ҏ(gu)无需再编制全局ID~码
4. {划Ҏ(gu)q个角色挂接的特效烦(ch)? 在配|表里添加播放指?/p>
q样做的优点:
角色引用到的资源才会(x)被打到最l游戏包? 不用的资源是不?x)被加蝲?/p>
cM? 在UIҎ(gu)? 也应该是要播放的特效挂接到对象? 而不是动态通过代码d?/p>
在Unity3D? Prefab图?Shader, Ҏ(gu), 脚本{一切^{看? 只要有引? 一ơ性加?
同时, 也可以通过静态工具分析Prefab.
如果是通过代码加蝲的效? 则只能让E序员做优化, q种q程无法让Unity3D官方后期提供的工兯行优?/p>
所? 推荐使用PrefabZ心的资源理模式
随即Q我们进行了分析。期初推断是arm64引v的问题,试调整为il2cpp同时启用armv7和arm64的通用包,问题没有解决?/p>
l箋分析Q因为游戏正常启动, 只是初次加蝲卡进度条Q?那么可以排除是arm64位问题导致的Q因为如果是不兼容包Q?在安装时直接?x)报出架构错误,无法正常安装?/p>
l游戏内部加入了一个HTTP日志pȝQ?l服务器报错。跟t了一ơ, l果发现了一些奇怪日?/p>
在检下载之前的加蝲没有出现M问题
但是下蝲错误报了两次Q?W一个错误在我们本机也会(x)报,但可以忽略?但第二个错误只有iTouch5QiPhone6s?x)出?/p>
报错后, 所有日志都出现了两ơ?/p>
Ҏ(gu)了下代码Q发C一些逻辑漏洞。但同时需要注意的是, q个bug的问题的核心?yu)是在这一个错误描qC
The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.
查过文章发现Qios9开始默认要求所有的app的HTTP讉K必须使用HTTPS加密协议保证安全
所以结合前面的试环境Q?证明q个问题定被修?/p>
Unity3D现在官方不支持热更新, 虽然有一些lua的热更方? 但鉴于项目开始时lua热更q不成熟, 所有没有采?
l过长时间业界和技术的摩擦, 渠道基本认同了Unity3D不能热更的现?
Ҏ(gu)我们q边q营分析的热更新的需? 临时关闭功能避免bug刷钱
在强力的QA支持(我们?? 可以保证版本的功能不?x)有明显问? 即便有问? 可以通过服务器关闭功能达到效?
q样来说, 代码上的热更新基本是不可能了, 只能通过服务器来配合, 所以我们只考虑资源热更新需?
场景: q部分属于PVE功能, 虽然包含有怪物摆放的逻辑, 但一般一旦做好基本没有更新需?
角色: 后期q块可能?x)考虑更新, 但明昄l上可以同时支持打包和非打包需? 因此默认包内的角色可以直接打? 未来的付费相关的角色热更新需求既可以通过
一阶段打包更新, 也可以根据增量更新进?
界面: 知识更新界面包只能修改界面布局和坐? 逻辑依然需要打包更? 所以这块完全有必要不做打包
Ҏ(gu): Ҏ(gu)与角色和界面兌紧密, 而且L(fng), 交叉的情况很? 打包明显?x)造成一部分资源重复q入包体, 因此果断不打?
ȝ下来, 资源的更C定是伴随着代码的更新来做的, 那么可以规划一个大版本, 把需要更新的资源和功能逻辑一块更?
虽然大包更新?x)损׃定的用户, 但未来在核心E_的情况下, 可以考虑把新功能用脚本来更新
资源不打包带来明昄优势: 资源加蝲变的更快? 制作程变的更简? 无需兼容打包和非打包情况. 包体大小有小q度下降( 重复打包部分)
每次Unity3D~辑器打开? q接服务器都?x)有一定几率失? 需要反复关闭再打开~辑?~4ơ后, 才能正常接收到封?/strong>
转蝲h? 战魂筑http://www.shnenglu.com/sunicdavy
我们的网l库ZC#的Begin/Endpȝ异步Socket, q种socket更接qC++的asio模型, 撸v来特?
1. Ҏ(gu)l验, q个诡异问题多半跟多U程有关p? 复查代码, 无效.
2. 扑֏人更换网l库, 换阻塞Socket实现和SocketAsyncEventArgsq种实现都试q? 仍然无法解决问题.
3. 接下来还是对Begin/Endpȝ|络库进行日志追t? 发现, 发送会(x)L成功, q接成功和接收封包有一定几率会(x)断掉
我们q没有单独开U程来处? 而是利用底层异步通知, 然后有线E安全队列切换到ȝE进行投? 因此底层的线E正常性是整个问题的焦?/p>
׃一直无法找到原? q个问题搁置?/p>
转蝲h? 战魂筑http://www.shnenglu.com/sunicdavy
直到有一个偶然的Z(x), 取过同事代码? H然发现W一ơ打开Unity3D~辑器可以直接登? 但之后又不行. 同事提醒, ?x)不会(x)是优先度问?
马上打开Edit->Project Settings->Script Execution Orders. 提高了网l组Z先度
试, 通过, 问题解决
转蝲h? 战魂筑http://www.shnenglu.com/sunicdavy
转蝲h? 战魂筑http://www.shnenglu.com/sunicdavy
一直怀疑这个问题跟Mono版本q老有关系, 但由?.2版本到年底才更新, 之前只能自己啃bug.
在这个问题发生后解决? 我们q有一个相兌? 我们网l部分比较稳定的代码拆分攑ֈdll? 通过Unity3D的机制进行加?/p>
l果, |络无法初始? 估计也是跟这个问题有关系
M, 有类似问题时, 可以试用脚本执行序大法q行试
Z让代码管理工兯识别Unity3D的asset格式, 做出一些少量的合ƈ?qing)识别修? 我们需要对Unity3Dq行一些配|以适应代码理工具.以下是步?
Edit->Project Settings->Editor里按如下配置
在做Z改前, 请将之前的修Ҏ(gu)交代码管?/p>
选项设ؓ(f)U框内的方式, 使用昑ּMeta Files, 以避免在资源理器里被被忽略的meta文g以及(qing)Asset文g使用文本格式
讑֮好后, 所有的资源重新序列化, 修Ҏ(gu)交代码管理工?/p>
代码理工具不是玩能? 也一定能很好的合q这些复杂文本格? 因此我们在多人协作开发中需要遵守一些原?/p>
1. 先获取别人的更新, q行无误后再提交( 最基本?)
2. Ҏ(gu)合ƈ的asset格式, 量查看其修改过E? 询问他h的修改与自己的修改差?或者是git?方合q?
3. 对合q误的asset格式, 应及(qing)时修? 手动合ƈ, 切勿延误q提? 影响他h
参考链? http://stackoverflow.com/questions/21573405/how-to-prepare-a-unity-project-for-git
工程参数讄
在创建时, 记得最下边的模式设?D模式
摄像机参数设|?/strong>
q里需要设定的?
Z设ؓ(f)-10, 如果设ؓ(f)0, 不可见物体
ClearFlags设ؓ(f)U色, 因ؓ(f)?D游戏, 所以无需默认参数的天I盒
Projection设ؓ(f)正交投媄(jing)(Orthographic), q是相对?D的透视投媄(jing)?/p>
SizeҎ(gu)你的设计期分辨率的半高度来设?比如设计? 我们以iPhone4的分辨率(960*640)计分辨率, 那么Sizep?40/2=320
_帧的导出
U3D原生支持对纹理Atlas的切片以制作_? 是通过SpritePacker来做? 不过介于TexturePacker的强大合q及(qing)U理分布优化, q里我们q是以TexturePacker来做例子.
TexturePacker 官方|站: https://www.codeandweb.com/texturepacker
需要合qAtlas的图片拉入TexturePacker, 然后参考上? 讑֮描述文g格式为Unity3D. TexturePackerؓ(f)我们导出一个png的纹理及(qing)一个txt格式的文? q个文本内部格式是json, 描述每个_帧在原图Atlas的信?/p>
讑֮U理对应像素寸
点击导入到U3D的pngU理, 在Inspector中奖Pixels To Units 讑֮?
默认q个值是100, 代表一?00?00高的U理在U3D中只?个单位大? 设ؓ(f)1? 是传统2D引擎? U理与屏q分辨率对应模式
转蝲, h?/em>http://www.shnenglu.com/sunicdavy 战魂筑
转换TexturePacker导出格式到Unity3D_帧格?/strong>
?a title="https://github.com/autolame/TexturePackerExtended" >https://github.com/autolame/TexturePackerExtended下蝲一个Unity的扩? q甩到工EAssets中导?/p>
在刚才用TexturePacker导出的txt格式文g上点d? 选择Process to animated Sprites
q种导出? 适用于以原始单图片中, 以图片正中心为原点的序列?/strong>
之后, Atlas箭头展开的序列拉到场景? 可以预览动M