找回密码
 立即注册
查看: 1112|回复: 18

[笔记] 那些事情是用Unity开发项目应该一开始规划好的?如何避免后期酿成巨坑?

[复制链接]
发表于 2021-1-10 09:00 | 显示全部楼层 |阅读模式
那些事情是用Unity开发项目应该一开始规划好的?如何避免后期酿成巨坑?
发表于 2021-1-10 09:02 | 显示全部楼层
总的来说,unity没有啥天坑。只要肯研究,后期都能改进,也都不会影响到上线。
小坑太多,说不完。unity上手容易坑太多,基本事件机制,生存周期,场景和资源管理,mono虚拟机的gc机制都是坑。

要说的话,真正影响到架构的是(排序)
1. 是否要用lua
2. (对于需操作的游戏)客户端游戏如何做战斗验证

-----------------------------------------------------
公司的话,推荐:
参加Unity年会
购买Unity的官方支持问答平台,人有源代码,还能找总部

-----------------------------------------------------
下面列举小坑吧。不建议都绕开,毕竟没有那么多时间做前期调研的。
对应版本Unity4.x

1. 客户端程序层面
总的来说C#超级给力的,不过别玩脱了

1) mono虚拟机gc
Unity的mono虚拟机使用不分代的gc算法,临时对象积攒起来,导致重量级GC游戏频繁卡顿。
Unity官方:认真review每帧20B以上,以及一次2K以上的GC Alloc的行为。传闻:Unity5会改进。
推荐阅读:
Gamasutra: Wendelin Reich's Blog
评价:请像C++一样精确了解各种行为的gc,foreach 都不要随便用。严重,但游戏是可以卡巴卡巴上线的。后期一位核心开发人员修2~3周。

2) 苹果aot编译问题:模板问题
mono在苹果上采用aot将C#编译为静态代码。首先,依赖于动态代码生成的复杂模板容易运行时崩溃;其次,mono会将客户端生成一个库。模板代码实例化容易膨胀导致该库超过40M而无法链接。
实战:碰到了改写法吧。不过我本人是静态类型检查派的。

3) 少用coroutine
yield只支持try--finally,与异常体系兼容性极差;难以提供返回值;异步本身是非线性的,很难保证逻辑完备
实战:复杂异步逻辑用状态机。不致命,多修bug也能抗过。

4) 自行处理配置数据序列化
严重影响配置读取速度。C#自带的xml序列化很慢,自带的二进制序列化也不够快。
实战:打包配置考虑protobuf或者代码生成器。中后期一周左右。

5) 反射
手机上jit情况下,第一次反射一个类很慢。乱用足够影响启动速度。

6) 本地化
如果公司习惯于做海外市场,一开始就可以考虑全套本地化方案。后期改需要一个人1~2个月工作量。

2 资源优化
Unity资源优化,一个靠谱的TA很重要。

1) 资源内存占用
512内存机器能用的资源大概只有50~60M。
需透彻研究贴图。考虑换皮怪资源复用、UI的图集合理化。
没有UI优化经验的话,强烈建议一个核心开发死跟,像抠代码优化一样优化图集总结经验。这个后期很难收场。
每个粒子发射器占用10K内存;有些项目在动画上会有内存问题。

2) 关注资源包大小
最大的是贴图和骨骼动画。贴图关注内存即可。骨骼动画可以占到模型的一半大小,重做的话有各种优化方案。但超标后期也很难收场。

3) 依赖打包
Unity4.x和Unity5完全不同。其中Unity4.x机制庞大繁杂容易错,要有心理准备。扯一些要点:
* 一定要搞清其内存占用和生存周期。要实测,特别容易跌眼镜。
* 每个API都有坑。我个人目前推荐压缩模式、LoadFromCache,此时不能拆太碎。战斗前预加载。
* shader加载慢,应当放入依赖包
* bundle不能重名

4) 场景、drawcall、camera
场景面多了考虑动态batching
不同材质透明物体(例如粒子)穿插可能引起drawcall暴增。
camera是重型对象,越少越好

5) svn
资源选Text模式、显式保存.meta,便于版本管理。资源分人或者锁了改,规避冲突。

3 Unity
和Flash一样容易学的3D编辑器

1 ) 事件机制
Unity事件机制很不好用。单个对象,Awake,Start,Enable调用时机相当复杂。Unity完全不保证多个对象的事件执行顺序,导致很多人绕开Start。不恰当的使用事件,很容易导致父子对象不在同一帧出现,画面不干净。
Destroy操作是延迟的,对象会活到帧的结尾,然后必定销毁。库级设计时,必须考虑到这一点(例如对象池/动画库)。

2) 资源管理
只说Unity4.x。合理做法是依赖很卡的UnloadUnusedAssets、LoadScene清理无引用资源(另注意前者是异步的),或者Bundle.Unload(true),这些方案各有限制。试图更细粒度手工清理的困难在于,并不存在系统性文档解释Unity资源的分类和生存周期,且Destroy操作很保守。例如,销毁mesh时,并不会销毁material、texture,更不会清理脚本资源。
此外,特定的普通操作会造成资源克隆。例如访问Renderer.meterial,Animation.AddClip。

4 NGUI
久经验证的掉链子王。新项目也可以尝尝uGUI

1) panel重绘
widget改变后,所在panel需要生成多边形,很慢,坑新人没商量,注意合理分panel。panel中多边形过多会爆(貌似是65535个顶点?)。
uGUI原理相同,就是c代码比C#快不少。

2) panel渲染顺序
搞清楚ui上放置3D物体咋办,ui如何和特效混合排序。

3) 策划/美术ui规范
潜规则很多。Anchor、动画不可作用于同一个物体。widget必须是panel的子节点,不然他就会自己造panel,经常搞出乱子。再加上上面的panel规则等,要策划美术折腾ui可费神了。
项目组自制UI编辑器自然是极好的,不过不一定必要。

4) 创建速度慢
由于序列化字段多,NGUI对象创建可导致卡顿。多状态对象不要靠隐藏-显示,而要动态创建。尤其是状态中包含粒子发生器/Animation,这俩还有内存问题(10K一个)。

5) 与Unity事件机制强耦合
与Unity的事件机制强耦合,不完备,容易有bug。例如,panel绘制依赖于LateUpdate。coroutine中同时关闭旧界面,创建新界面,此时当前帧 LateUpdate 已过,表现为有一帧画面为空白。

----------------------------------------------------------------------------------------
正文分割线

Q:回答Ye Deng在评论区的问题  “能详细说说使用 UnloadUnusedAssets()、LoadScene() 等等 APIs 的细节吗? 有没有替代方案 ”。

A: 需要区分 SceneMemory和Asset。Instantiate出的GameObject及其Component属于SceneMemory。贴图、Mesh、Shader、自定义Component代码、AnimationClip等,还有AssetBundle中的GameObject及其Component属于Asset。

    Destroy 仅删除SceneMemory对象,不删Asset。
    UnloadUnusedAssets、LoadScene 检索代码堆(不检查栈),删除所有未引用的Asset。
    AssetBundle.Unload(true) 删除bundle自有Asset。
    DestroyImmediate 删除Asset

说一下UnloadUnusedAssets慢的原因。核心问题在于,Unity希望C#代码可以引用资源,而且能维持其资源生命周期。然后Unity决定每次UnloadUnusedAssets都去扫描所有C#对象!这个挺慢的。

从API看,下面是比较原汁原味Unity的模式,都避免了关卡中间UnloadUnusedAssets:
A. 静态关卡
关卡进入前加载所有资源,在关卡结束后一次性清理。特别的,Unity觉得你应该使用Scene,他的lightmap、navimesh都是与Scene绑定的。这种情况下,都不需要调用UnloadUnusedAssets()。优点是关卡非常流畅,但是关卡必须是有限大小,有限内容。

B. AssetBundle为单位管理动态资源
动态资源放到AssetBundle中,不再使用时,用Unload(true)彻底删除Asset。缺点是和A方案比起来加载可能会卡;此外不卸载的bundle本身,合到一起经常有10~30M的额外内存占用。

具体游戏,怪物、特效、UI、玩家用A还是B就是权衡问题了。

最后,如果觉得Unity不好,可以考虑全手动管理资源,能绕开一些限制,多榨一些性能。如果项目可以有一个人专门深度优化技术,可以考虑尝试,时间两个月起,也会引入不少bug。不少项目是主程做这事,也有让较厉害的程序做这的。
发表于 2021-1-10 09:06 | 显示全部楼层
各位答主说得都感同身受,一看就是过来人,我也来说说。
(以下所说主要是讨论有一定规模的、参与者比较多的大中型项目)
1、典型例坑:新手引导。

新手引导可能是常见工作中坑最大的系统之一,这个坑到底有多深?
    强引导和弱引导。不能改动源代码。实现高亮显示。进行到一半时如何存盘、如何恢复。
1、强引导玩家必须跟着引导的步骤走,弱引导是玩家可跟着走也跳过,跟着走就会触发强引导指导这个引导步骤一直执行完成,跳过就跳过了。
2、不能改动源代码。按道理确实不应该改动别人代码的逻辑,可在实际开发过程之就会发生玄而又玄的对接不上的问题,当新手应道解决不了的时候,问题就会被抛掷到其他功能上。
所以最后的问题应变成了“新手引导和其它功能如何才能对接上”。这是需要在项目一开始的规划好呢,还是在功能系统做好以后再考虑呢?
3、高亮显示不多说有很多种做法。但通常的问题是要等到某个界面加载完成以后才去找高亮显示区域,还是反其道而行之一直检测高亮显示区域直到找到高亮显示区域?
4、很多BUG发生在处理新手引导时、完成了一半又意外中断。这个测试人员经常测不到所有情况,但是总有玩家能玩出各种BUG来。
2、资源管理

资源管理的重要性,怎么强调都不过分。这东西没什么难的,但是为啥特别强调呢,因为它影响了:
    美术、策划、程序工作流程。资源找不到、命名错误、格式错误等常见问题。(良好的资源管理可以帮助自动检查、尽快发现错误。)统一管理资源,直接关系到打包。影响包大小,下载速度。影响资源加载速度。项目后期,素材质量和游戏性能之间需要反复调优,这一步如果前期做乱了,最终优化工作就很艰难。
Unity提供了多种资源管理方式,但是对中大型项目来说,一定要设计一套符合项目的资源管理系统,各部门用熟了就好了。程序加载和使用资源要走统一的方法,但也别搞的太复杂。
这一点非常同意由主程设计系统、专职TA辅助管理。
3、大项目要避免大量拖拽操作,或依赖于编辑器的设计

Unity的可视化操作非常酷,把字段暴露在编辑器面板上,拖一拖就能完成各种编辑。
但是……在大型项目里一个界面数十个需要拖拽指定的字段,简直是悲剧之源。一不小心鼠标滑了,那就有的找了。
同样的问题也存在于节点顺序上,如果依赖于Hierachy中子物体的顺序,那稍微加一个GameObject,或者拖一下顺序,可能瞬间全崩。
特别对于界面繁杂的游戏来说,你会发现宁可在C#代码中啰嗦一大堆,也不要把字段随便暴露出来。代码一般不会有人乱动,而且代码可以diff、merge,查错很容易。但是编辑器的信息全部分散保存在meta等文件里,出现问题八成要加班了。
更高级的做法是用规范的函数或者干脆用配置文件,把规则规范起来。
深入思考这一点,会发现很多其它答案中提到的问题,都可以归结在这一点中。
所以对很多项目来说,宁可代码写的“笨”一些,也不要依赖于编辑器设置。
4、同上,初始化顺序也有类似的问题

如果多个系统都把初始化写在Awake和Start里,那你就真的不知道谁先启动、谁后启动了。虽然Unity提供了神奇的Script Execution Order来强制脚本之间Start的顺序:
但是这种做法我觉着很像是补丁之上套补丁……不是一种良好的模式。


总结:要多相信键盘,不要相信鼠标【笑】。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2021-1-10 09:08 | 显示全部楼层
与其他商业引擎不同,Unity最大的特点不是流程化,工具链化,而是通用性。通用性高的特点就是上限极高,高到秒天秒地秒空气的那种,下限极低,低到人神共愤拖出去枪毙五分钟的那种。
Unity的2018版本不是技术进步的版本,而是填坑的版本,这个版本的更新更多的是在弥补之前留下的大坑,比如广为吐槽的性能杀手Mono VM + GC,缺乏可靠的内存管理机制等都统统得到了官方的重视,并提供了一系列新特性来搞定这些说不大也不是很大但是又挺恶心的小坑。
那么我们就以最新版为标准,谈一下现在一些要避免的坑。
    团队人才储备,是游戏开发最大最深的坑。
现在看到大多数团队开发到后期,遇到工作跟不上,老坑没解决,新需求又不断飞来,基本可以归结到人才储备<工作量,许多前期的Trick为了快速完成工作,给后期的扩展带来极大的困难,我在这篇文章中详细分析了本人参与过的项目的性能短板:
MaxwellGeng:漫谈Unity渲染管线的流程化设计其实可以看到,这里边反映出的许多的问题,属于一种前期没想优化,后期无力优化,最终结果就是性能硬指标达不到,需求完不成。解决这个问题的关键在于制作人的意识。制作人是否能意识到,在前期项目开始时就应该保证后续的高级开发者人才的输入,保证人力能跟得上。比如游戏逻辑,游戏逻辑是数位有成功项目开发经验,顶尖大厂开发经验的老司机(程序,策划等)经过讨论确定的?还是随手写个Update就往上拖的?设计和美术方面,是综合考虑游戏性质,流程成本,市场爱好,还是仅仅因为“我觉得这样好看”?好不夸张的说,有经验和实力的团队在拿到需求时,可以比没有经验实力的团队少90%的坑。
2. 磨刀不误砍柴工,造轮子不是耽误开发:
育碧的地形创建工具链效率十分恐怖,这少不了“磨刀”的工作。比如,在项目前期养一只引擎组,一只TA组,专门配合美术开发,在项目前期写逻辑时把一部分精力放在框架搭建上,并尽可能多的和策划讨论需求扩展,对“可能被改需求”的地方做更多的准备。这些工作都不是无意义的。
如果项目开发团队能意识到以上两条并做了充足的准备,可以说一款成功的大作已经成功了一半了,先占个位置,过段时间再补充一些实际操作方面可以避免的坑。
发表于 2021-1-10 09:10 | 显示全部楼层
说个不大不小的坑吧:DLL模块要事先规划好。

Unity会根据Folder自动将所有代码打包成4个DLL,其中两个是Editor的,两个是游戏的。
当项目比较大的时候AssemblyCSharp.dll.o在连接时会报连接错误。
为了解决单一DLL过大的问题,最简单的方法就是将代码“分摊”到Plugins文件夹里。
因为外边的代码对于Plugins里头不可见,所以如果代码的依赖关系一开始没有理顺的话,这将会是一个非常痛苦的过程。

因此,尽量在项目初期就确定好DLL的划分(其实本质是代码的单向依赖关系),游戏无关的底层代码尽量往Plugins里头放。能单独做成DLL的一定要提出来打包。

代码结构理顺了项目后期会省不少事的。
发表于 2021-1-10 09:14 | 显示全部楼层
还记得一个著名球星说的话吗?我最精彩的进球永远是下一个。

做了四个小游戏,每次完成之后都会收获良多,下次重复去做的时候,就会少走很多弯路,代码结构更清晰,资源管理更恰当。很多坑,你自己走过之后,才会明白和领悟。加油吧!一开始就规划好是不现实的,人生本就是个摸索的过程嘛。哈哈 unity初学者,spritekit使用了八个月,欢迎交流。
发表于 2021-1-10 09:21 | 显示全部楼层
楼上的NGUI好用的很,我基本没遇到什么问题,必须升级到3.0以上版本。
说说我所看到unity相关的,不好的习惯:

1    尽量不要在Awake(), start()等函数内加入业务逻辑的初始化代码。首先无法简便的直接启动调试查看。逻辑代码依赖太多,很多时候你只是希望检查界面编辑效果,在你不加入逻辑代码直接启动的话,基本会出来一大堆错误。另外,各个脚本start等函数的调用顺序很难控制,不要说可以调整脚本优先级,这个功能大致用用可以,不要依赖它。更何况很多人甚至不知道这个功能。初始化必须要显式调用,除非你知道自己在干什么(比如一些单纯的效果类脚本)。

     2    不要public太多的变量到编辑器中,特别是逻辑变量。尽量减少脚本外部引用特别是对GameObject的引用。这对维护来说真的是一个梦魇,死的很难看。

     3    一个Level内,要控制它的tree层级。你能想象一个MainMenu的level,直接包含了所有的UI,他们直接的脚本相互之间引用Level内GameObject。你能想象一个主脚本内有几十个引用到外部GameObject的变量吗? 单是要在编辑器内找到这些变量对应的GameObject眼睛都要瞎掉。有时在缺少信息的情况下只能靠猜的。应该把每个功能独立开来做成预制件,每个功能有管理自己的独自脚本组,然后再添加到主level内。这是基本的模块化而已,不能因为unity太好用就可以乱来。

     4    有人似乎意识到了自己public出来的变量太多了,或者纯粹是懒得加了,于是当他确实需要引用某个外部GameObject时,通常都用someobject.getchild(i)来取得引用。 这绝对是值得捅一刀的行为,你的项目如果有人这么用,不要我说了吧。除非父节点之下是一个节点链表(如滑动框集合),否则谁知道getchild(i)得到什么意外?我就发现往某个节点增加了一张图片,然后整个模块的逻辑全乱掉了,这简直是谋杀未遂啊。

     5    管理规划好你的NGUI的depth。2.7版本以下不要随意移动z轴和depth来达到显示效果,永远要有一个基本depth参照值。设计好atlas的划分,如果你不想遇到增加或减   少一张图片就会遇到奇怪的遮盖或消失问题。特别是你的level很庞大时,我发现无解。强烈建议升级到NGUI3.x,痛苦但值得。

     6    coroutine是个好东西,但别滥用。实现一个状态机是有必要的。别的不说,至少不会在所有模块的各个角落里都添加上新手指引的代码了吧?建议仿照boost的statechart写一个简化版本,爽死你。

     7    善用uigrid,uitable。当你写一个背包UI时,还要手动写每个格子的长宽,padding逻辑这是折磨自己,坑死别人,何苦。

     8    规划好你的object的结构,这通常比你所写的脚本更重要。更一般的说,数据结构简单易懂,直接反映问题,这样你的逻辑代码才会清晰简洁。

     9    设计不要超越或强迫程序。比如,要求一部分UI背景处在3D背景之后,其他UI的在3D背景之前,而这个3D场景是游戏主场景,忘了说你还要照顾在这之间穿插的粒子效果呢。我无法理解这种给自己下绊的尴尬决定是如何诞生的。可能2个原因吧,一是之前程序使用NGUI2.7,整个3d场景的layer被设成跟UI一致(无法想象),然后程序通过z轴和depth来达到这些效果。看到这我已经很凌乱了,而且居然无法说服他们这是不对的...

     10    资源命名有待规范,目前资源包括预制件的命名混乱随意。这个是整个项目人员素质问题,或者说缺少个规划。

     11    atlas的资源分布好好好规划。美术风格上尽量使用通用的控件,通用的控件使用的atlas限制一张之内。不要鬼扯什么设计不美观的问题,一张2048x2048的atlas大小,都容不下你惊人的设计能力?特殊的图片按照level或加载状态分好atlas。尽量做到动态创建销毁。不要包含过多的大图片,能从设计上避免就避免。

     12    我真的不建议把UI直接跟level做在一起。如果是轻UI类型的项目可以。做uiniy要时常考虑一点就是,level,prefab,atlas等等都是个二进制文件,svn下不可比对,意味着你修改某个东西时,在这个level下的所有东西都要被锁定了,其他人只能等你。

     13   SDK接入时,养成代码里就做好平台区分的习惯,用宏加上状态机。因为SDK是个巨坑,先保证己方代码不出错,才能自求多福啊。平台区分代码(宏),尽量都放在相同的代码段中。

     14    c#的话,模板可能会是个问题。我会告诉你相同的模板代码,在andriod下build通过,在wp8和ios就不行呢。写的朴实点了。

     15    资源方面,请试着封装一个resource manager。加载资源,prefab,level等时想着bundle。到处resource.load是不行的。这是个蛮头痛的问题,我还没真正开始做,异步加载估计有很多问题等着。

     在可编辑性和代码控制间权衡好是使用unity的很重要的问题。

      unity是个编辑器,意思是不只是程序员用它。请所有相关的开发人员熟悉基本的工作流程与概念。
发表于 2021-1-10 09:30 | 显示全部楼层
转自博客:Effective Unity3D

以下总结一部分来自经验之谈,一部分来自其他人的分享。总的来讲,Unity开发原型和效果、验证想法,确实是无比便利。可能一个月就把核心玩法做得差不多。强大的编辑器功能让我们也有很大的可扩展空间来协助我们开发工具。可是编辑器是把双刃剑。如果提前看清楚有什么坑在前面,或者其他人踩过什么坑。我想这会对项目风险的把控会有很大帮助。
避开unity的坑
    尽可能制作抽象的prefab来做关卡编辑,该prefab应该足够抽象简单(只有一个GameObject,然后通过Gizmo来绘制是个不错的手段),否则以后变化的时候(常见的就是改美术资源),所有关卡都lost prefab,那么对策划来说是一场灾难。可以考虑通过数据表+编辑器的方式来提供策划操作同时也不再需要担心lost prefab的问题。prefab越简单抽象越不容易丢失,prefab之间嵌套的正确方式是通过链接而不是挂在节点下面。
    尽可能避免修改Scene,方法有几种:
      使用xml之类的数据组织场景尽量多让scene由prefab组成,这样变动都在prefab上使用工具做场景Merge
    不要过度依赖Component特性来开发,考虑数据驱动。逻辑容易散落在编辑器各处,可以做一个中心管理。
利用unity的特性
    组织好hierarchy,不管是编辑的时候还是运行的时候,编辑的时候可以通过工具来简化组织层级的工作。让每个场景自己能跑。利用基于组件的架构,尽可能少的使用继承(用C#的话),多通过组合来完成开发。遇到需要数据访问的通用接口,我们可以通过组合的方式来完成,而不是提供一个公共基类接口来继承,只要大家都认识这个公共组件就可以取到数据了。遇到通用的事件派发,我们可以用字符串拼接的方式派发到指定的对象或者更参数组合派发事件到对象身上。框架采用星型架构+事件机制,由于Unity3D没有一个所谓的入口函数,不利于代码跟踪,这样的基础架构能带来很多便利。unity界面扩展能力很强,而且借助CLR(commom language runtime)的反射能力,C#里面开发界面非常容易。做好tag、layer规划,要考虑业务中哪类物体之间需要交互。在代码里面get某个prefab或者GameObject,可以考虑利用界面拖目标过来,这样更加直观,而且也能对抗变化,比如目标名字变了也不怕,而且还能节省代码量。
代码这里针对C#,静态强类型面向对象本身就是一个坑,继承带着两个职责,一个是复用代码,一个是接口继承。虽然性能比lua高那么一丢丢,因为性能瓶颈不在业务本身,设计上的问题要严重得多。我认为像lua这种动态语言的元编程才能够贯彻单点真理,通过元编程把真理推导到系统的每一处。让代码始终保持语义,而我认为写业务代码最重要的是保持语义。保持语义的简单有效评判方法就是看这个类中的某个函数,单独看它能否看懂;多个接口能否组成完备的解决方案。静态强类型面向对象语言比较适合需求稳定的严谨的系统开发,而不是游戏开发。容易经过多次的策划需求冲刷,语义很容易扭曲,各种抽象泄露、各种hack。好吧,跑题了。
    Unity3D容易被破解,因为发布版本的IL是非常容易被反编译的,要做好混淆的考虑。在Unity3D中混淆要考虑对编辑器的影响。复杂类型尽量使用引用类型,值类型反射麻烦,不方便序列化以及做成编辑器。值类型要小心赋值对象是否只是临时对象。引用类型释放之后,引用它的指针会置为null,可以放心使用。foreach、linq、协程慎用,反射只在编辑器中使用。考虑封装Time,方便做暂停。考虑使用调度器来完成功能,而不是在Update自己维护状态,这样做暂停也很容易,代码更清晰,功能更内聚。增量更新要一开始就想清楚。
美术
    Unity3D可以通过扩展编辑器让非技术人员编辑界面来工作,组织好美术资源规格、路径,并且自动生成prefab。游戏场景物件也要规划好逻辑节点,这个也应该通过编辑器扩展好。复杂功能也应该通过编辑器开发给策划微调,特别是可视化比较重要的模块,比如动作调整。制作原型美术,让开发提升开发效率。有统一的约定,比如模型总是中心对齐,角色总是脚部对齐,统一的缩放、统一的动画骨骼命名,资源有统一的路径。支持换装(avatar)要一开始就想清楚。资源加载和优化尽可能早地给出雏形(只是雏形,帮助你对需求的把握,因为这时候你还不知道热点在哪),因为一旦没有规划好异步和资源释放,那么阻塞卡顿和内存飙升那是意料之内的。因为有雏形,那么代码会间接一点,也为改变提供了空间。
发表于 2021-1-10 09:30 | 显示全部楼层
1.整个项目使用的语言,是使用C#还是Unity Script。不建议两者混用,到了后期如果引入plugin可能会引起麻烦。C#已经是最流行的语言,Assets Store里90%甚至更高的插件是用C#编写的。

2.如果以后准备跨平台部署(Win,iOS,Android,WP等)在序列化反序列化的代码一定要小心。由于iOS纯AOT的特殊性。导致Emmit代码无法运行。因此在其他平台能够运行得很好的程序到了iOS上要么编译不过,要么运行直接闪退。建议先以iOS为目标平台开发并实机测试项目。保证兼容性。

3.scene的内存管理。不要一味的在一个scene中堆砌太多的东西,在Editor或者pc上跑起来很顺畅的scene,会因为场景里物体太多在手机内存不足上直接闪退。到那个时候再来减少物品或者分拆scene就会很痛苦耗时了。在制作之前就好好的规划划分scene,以满足手机内存需求

4.如果是新项目,强烈建议使用Unity 4.6.2以后或者最新的Unity5来进行开发。2015年6月以后苹果所有的项目都需要满足64bit发布。这个支持只有4.6.2或者5才支持。而由于Unity后台使用了一个新的IL2CPP技术,导致原来的代码在新技术编译下会出现各种问题。老项目请尽早升级Unity并尝试IL2CPP编译以确定并解决问题。
发表于 2021-1-10 09:40 | 显示全部楼层
程序功能、架构尽可能的先想清楚。多人开发的话,同步机制也要理清楚。最好是建目录相同的两个工程,一个是客户端工程,另一个是美术资源工程,并且要有专人核对美术资源工程,或是专门开发个检查错误的小工具,来保证资源上传的正确性。
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-22 18:16 , Processed in 0.135651 second(s), 27 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表