问题1: 委托是什么? event 关键字有什么用?
委托是一个容器,可以放函数对象,并且可以触发委托面的每个函数调用。委托主要用户回调函数。
public delegate void GreetingDelegate(int lhs, int rhs) ; // 定义一个委托类型
public GreetingDelegate MakeGreet; // 定义一个委托变量。
MakeGreet(3, 4); // 触发容器里面所有函数调用
我们如果在外部给委托变量加函数进来,那么委托要定义成public, 这样做又有一个问题,public外部的人也可以触发这个委托,如果我希望设计成外部可以加回调,但是只能是模块内部触发委托,那么我可以加一个event来修饰,这样虽然是public,但是外部无法触发委托,只能类的内部触发。
public event GreetingDelegate MakeGreet;
问题2: Unity 摄像机有几种模式,成像的原理是什么?
Unity 摄像机有两种模式一种是透视摄像机 ,一种是正交摄像机,透视摄像机成像的原理是利用相似三角形来成像,如下图
正交摄像机直接投影到屏幕成像
问题3: UGUI如何打包成图集?
UGUI打包图集分成几个步骤,如下
Step1: 开启UGUI的图集模式, Editor->Project Settings 下面有sprite packer的模式。Disabled表示不启用它,Enabled For Builds 表示只有打包的时候才会启用它,Always Enabled 表示永远启用它。 这里的启用它就表示是否将小图自动打成图集
Step2: 为每个UI图片制定要打入的图集的tag名字。
Step3:打包生成图集Window ------>Sprite Packer, 点击Pack即可打包生成图集。
问题4: UGUI 如何实现UI物体淡入淡出?
UGUI里面比如Image这些组件,都继承自Graphic类,这个里面提供了一个方法:
Alpha: 目标的alpha值
Duration: 渐变的时间
ignoreTimeScale:是否忽略Time.scale
void CrossFadeAlpha(float alpha, float duration, bool ignoreTimeScale);
问题5:Unity [MenuItem()], 其中[]是什么意思?
C#里面[]表示的装饰器,和Java里面的注解是类似的,我们可以通过Api函数读取到装饰器。比如,Unity Editor模式下的[MenuItem(“菜单”)]来装饰一个函数为菜单响应函数,那么为什么加了[MenuItem(菜单)] Unity就会生成这个菜单呢?Unity 读取MenuItem这个装饰器,知道这个装饰器的路径,这样根据这个路径在菜单创建一个路径出来,利用C#的反射保存这个装饰器所装饰的方法,这样点击菜单就调用这个方法。
问题6: 打包AssetsBundle包出来后.manifest有什么作用?
.mainfest 是一个文本文件里面有ab包的校验码,依赖以及资源内容等相关信息,这个信息是给开发读的,同时这个信息也作为二进制打入了ab包里面,所以使用ab包资源的时候,可以不用带.manifest文件。
问题7: Image与RawImage的区别?
Image是UGUI里面显示一个图片的常用的组件,他支持图集,单独的图片。一般我们显示图片都用Image组件来显示,因为图集能够把同一个图集里面的图片合并drawcall,这样提升性能。Image支持九宫格等模式。
RawImage组件是UGUI显示单个单个的图片而用的,它不支持图集,所以不同图片的RawImage单独占一个drawcall, RawImage可以直接修改贴图的uv参数,这样可以调整图片的显示。类似与打飞机的滚动的背景就可以用RawImage来不断修改uv坐标来实现背景图片的滚动。
问题8: Unity有哪些特定的文件夹名字,有什么作用?
Unity项目中有常用的一些文件夹的名字,这些文件夹的名字是Unity规定的,他们分别的作用如下:
Editor: 这个目录下的代码和资源是编辑器的Editor模式下的代码和资源,不会打入包体中,也不会在运行的时候执行。
Resrouces: 使用Resources.load加载的资源都要放到这个路径下,不管这个资源有没有用都会在打包的时候把这个路径下的所有资源都打入包体。
StreammingAssets: 可以使用UnityWebRequest 来加载本地的文件,这个文件夹下的所有文件都会被打入包体中,加载的时候可以使用web 的方式来加载。
Plugins: 用来存放插件的各个平台的目录,比如x86, android, iOS等。
问题8:如果项目需求要打空包,你如何处理?
项目需要打空包,我们在开发的时候,场景不要放任何内容,不然随着场景打包资源也被打入进去就不是空包了。同时Resources与StreammingAssets也不能放资源包,这样才能打出空包,我们如何使用资源呢?只有一条道路,就是从服务器上下载资源Ab包,再用代码把资源运行的时候添加到场景中。
问题9: 如果你是架构师,资源管理你会如何做?
资源管理是Unity框架设计里面很重要的一个模块,我们先来分析需求,资源管理的需求有1:代码加载资源与资源的释放接口
2:完整的资源更新机制与管理
3:支持打空包的同时,也支持打普通的游戏包。
4:做好版本管理与渠道管理。
做到第一点需求,如果我们用Resource.load来加载,那么打空包资源更新就非常不方便。所以放弃Resources, 同时又要代码加载,我们采用纯AssetsBundle机制来进行设计。所有的资源都基于AssetsBundle来进行管理,加载,释放。AssetsBundle本身有完整成熟的更新与解决方案。打空包也方便,把ab包部署到服务器,第一次运行先下载到本地,后续从本地加载ab包。在打包Ab包的时候,分渠道,分平台,生成不同的ab包资源。如果不打空包,只要把这些ab包放入StreammingAssets目录下这样用StreammingAssets的方法来加载ab包。先从ab包下载目录加载,如果没有,就到StreammingAssets目录下加载,这样永远加载的是最新下载的,其次才是在包体所带的。
问题9:Unity项目开发中程序如何愉快的与策划沟通?
在游戏发中,策划希望能方便的改游戏数值,游戏数据,能够灵活的编辑一些规则,这个是策划希望的,并且策划在改数据的时候,不用问程序,马上就能抛出效果,策划在改规则的时候也希望如此。规则一般提现在怪物AI等方面,数据一般提现在数值计算方面。如果是怪物AI等行为编辑比较多的,我们可以提供给策划行为决策树等编辑工具,让策划编辑行为和决策。数值计算,我们提供好数值策划表解决方案,让策划非常方便的修改里面的数据表等。游戏的地图制作,也是策划经常要干预的地方,Unity项目开发中地图编辑器要做好。
问题10: Unity项目开发如何避免多人开发是的提交冲突?
在团队项目开发中,由于大家各自开发格子的模块或同时开发交叉的模块。就会导致了一些项目提交时候的冲突,Unity开发中如何避免冲突或者有冲突的时候非常方便的合并呢?
这边的话提供几个经验供大家参考。
1:代码冲突的合并,这个相对比较简单文本合并即可,很多版本管理工具自动就能帮你合并好。即使有冲突,人眼很快就能解决,毕竟都是文本代码。
2: 游戏场景冲突就不那么好合并了,因为游戏场景本省不是文本,同时合并的时候可能会导致一些参数要重新指定等,所以很多Unity项目不会往场景里面放任何内容,而是把内容分成一个一个的预制体,每一个人负责一个预制体(视图)。尽量避免多人同时操作一个视图。
3: 不要在视图节点上直接挂代码,也不要在代码上直接绑定视图的节点组件等,这些都不利于代码冲突解决,全部都通过代码来完成。
总结一下: 避免多人修改同一视图,视图上不挂脚本,全部通过代码来控制逻辑,代码提交冲突非常方便解决。
问题11: Unity Set Pass Call是什么?
绘制一个3D物体的完成的流水线我们叫做Pass, Unity引擎绘制物体之前,先要给GPU流水线来装载对应的Shader设置相关Shader参数,这个叫做SetPassCall, Set Pass call发生在切换Shader的时候,这个性能开销也比较大,所以我们要尽量避免不断的设置与切换Shader,同时常用的Shader要缓存到内存里面,这样每次切换的时候速度会比较快。
问题12: Unity DrawCall 是什么?
Unity绘制一个场景的时候,把场景里面的物体分成几个批次提交给GPU绘制就是几个DrawCall。
问题13: 降低DrawCall对性能提升的意义是什么?
降低DrawCall, CPU可以把绘制的数据一次提交给GPU,比多次提交性能要好,同时GPU绘制的时候一次处理的越多,GPU的吞吐量就越多,就越能发挥GPU的性能。
问题14: Unity 是单线程还是多线程的?
Unity可以支持用户自己开发使用多线程, 比如用户做网络模块的时候,可以开一个线程来做网络消息的读取等。所以Unity支持多线程开发。Unity框架里面是两个线程,一个是main thread,一个是render thread, main thread负责业务逻辑线程,跑Mono代码,物理引擎代码等,render thread负责处理绘制相关,将绘制相关数据提交给GPU。所以unity内部是多线程的,Unity的很多API与场景组件相关API必须要在main thread里面调用,不能在其他线程调用。
问题15: Unity有哪些合批方式可以降低DrawCall
Unity合批的方式有静态合批,动态合批,与GPU Instancing合批,三种方式可以合并DrawCall。
问题16: Unity 如何分析内存占用?
遇到内存问题的时候,我们经常不知道如何优化降低内存的占用,其实处理这样的问题并不难,你首先要分析出来那些地方占用的内存比较多,把内存占用比较多的地方分析出来才是优化的首要关键。Unity提供了Profiler工具,可以查看内存的占用情况,如下图,
问题17: Unity 如何分析性能热点?
项目开发的时候对代码进行优化,提升代码性能。那么提升代码性能要找出来哪些地方是性能的热点,才是最重要的,假如你花了100分的力气,去优化一个,性能占用只有10%的地方,这样优化出来的效果也不会提升多少,所以我们优化性能一定要从优化热点下手。
如何找到性能优化热点呢?Unity提供了Profiler工具,帮我们把性能的热点函数都分析出来了,你可以根据时间占比,调用次数,来优化相关的时间。如图:
问题18: Unity如何查看当前场景的DrawCall?
Unity如何查看当前的DrawCall, Unity可以通过profiler和Stats来查看当前DrawCall的占用,Stats 如下图:
Profiler如下图:
问题19: Unity 是否能开发微信小游戏?
目前Unity还无法直接开发微信小游戏,Unity官方开放的tiny目前还只是测试版并没有对外发布,如果想要开发微信小游戏的Unity小伙伴们,可以学习Laya来开发,Laya利用Unity编辑器做场景编辑,有自己的游戏引擎,开发API接口与Unity很相似,学起来很容易上手。
问题20: 如果求两个向量的夹角?
夹角指的是两个向量之间比较小的那个角,夹角的范围[0, 180]度;
向量1(x1, y1, z1), 向量2(x2, y2, z2) 根据向量的点乘可以得到下面的等式:
点乘=|向量1的模||向量2的模|cos(夹角) = (x1x2 + y1 * y2 + z1 * z2)
这样就可以算出cos(夹角) = (x1x2 + y1 * y2 + z1 * z2) / (|向量1的模|*|向量2的模|)
再利用反三角函数,就能算出夹角了。
问题21:模型坐标,世界坐标, 摄像机坐标分别是什么?
模型坐标是美术建模的时候,会确定一个模型原点,基于这个原点,来建模每个顶点的坐标,这个坐标叫做模型坐标。
当把模型放到时间的某个位置,模型原点在世界的某个位置上,这样,模型的每个点的坐标就是模型原点世界坐标+模型顶点相对于模型原点坐标。
我们绘制的时候是从摄像机的角度来绘制的,所以绘制的时候,要将世界坐标转到摄像机为原点的坐标系下的坐标,转完后这个坐标就是摄像机坐标。
问题22: Unity Lua做热更新的优点与缺点
Lua 是目前Unity 热更新里面比较成熟的解决方案,Lua的方案一直很成熟,Lua执行性能也不错,特别是系统代码,由于LuaJit的原因能获得和原生接近的性能。同时Lua还可以修正C#的bug。缺点是Lua需要Unity开发人员在学习一种编程语言,同时Lua是弱类型编程语言, 不方便维护, Lua调用C#的API性能方便相对差一些,要减少这里的调用。很多Unity的性能分析工具对Lua支持不全面。
问题23: Unity框架设计中常用的设计模式有哪些?
Unity框架设计会用到一些设计模式, 这些设计模式能帮助我们很好的组织好框架设计与项目管理。Unity开发项目里面常用的设计模式有:
单例模式: 框架里面的全局单例的管理对象都可以用单例模式比如:网络管理,UI管理,资源管理等。
观察者模式: 框架设计中的事件管理模块对事件感兴趣的人订阅事件,触发事件的时候通知每个对事件订阅的人这个是观察者模式。
工厂模式: 编写一个构造工厂,构造出来同一大类的不同子类的物体。
还有一些常用的模式。大家可以根据具体的项目来总结。
问题24: Unity如何设置到后台后还运行呢?
普通的Unity调试或打包成pc版本的时候当游戏失去焦点的时候,游戏画面就暂停了,那么如何让他在失去焦点的时候还能运行能,可以通过设置Player Setting来设置,菜单如下:
File->Build Setting->Player Setting
问题25: Unity如何做地图切换?
Unity切换地图这个是非常常用的功能,我们一般在地图的出口处加一个碰撞器(Sensor属性要开启),当我们检测到碰撞,就可以开始切换下一个地图这样角色就进入了下一个地图的入口那里。
问题26: Shader代码编写中要注意哪些?
1:控制矩阵和向量的计算顺序。减少矩阵乘法。
2: 尽可能避免if等分支选项
3: 尽可能减少 cos、tan、pow等数学函数
4: 尽可能减少纹理采样数量
问题27:Unity性能优化常用的工具有哪些?
1:Unity Profiler。deep profile。
2:Miku-LuaProfiler
3:Frame debugger
4:Snapdragon Profiler或者RenderDoc
5:Xcode的instrument
6:Intel GPA
问题28: Unity做手游开发的时候资源规格控制标准一般是哪些?
1:模型角色高模 6000+面,低模 3000面。顶点数不定,因为顶点存在共用的情况,所以顶点数量可能是面数的两倍,也可能比面数低。纹理使用1024大小的贴图。低模纹理大小减半。主角因为有高低模,所以不开mipmap。个别精度比较高的npc(有UI显示需求)需要开mipmap,否则场景中会有明显的闪烁。
2:场景的drawcall控制在200以下。个别场景因为美术需求,drawcall可能会更高一些,但是SetPassCall也要尽可能保证比较小(材质尽可能共用,可以有效减少SetPassCall)
3:场景的面数在100k~300k之间都是合理的数值。
4:UI的drawcall100以下,一般就是三四十常驻UI Drawcall。
问题29: Unity如何做场景性能优化
1:要勾选StaticBatch,但是不能滥用。有color、uv3的,顶点超过4000个以上的,数量超多,但是同屏显示不多的模型。这些都不应该勾选StaticBatch。否则会导致包体积明显增大。因为StaticBatch会把模型都build到场景的ab包内。
2:注意压缩纹理的使用。法线应该用etc2,ios下用astc6x6,法线需要更高的精度,要避免压缩纹理导致的失真。
3:避免模型和贴图勾选 readable选项。这个可以在模型和纹理导入的时候做设置。
4:光照贴图和shadowmask图的压缩纹理选项。ios下可以统一使用astc6x6。android下shadowmask图使用rgb16,否则阴影会有明显的模糊或者锯齿。lightmap图倒是没有太大限制,尽量使用压缩纹理即可。
问题30: Unity如何控制目标帧率?
控制帧率。现在高刷新率的手机非常多。不要直接使用VSyncCount控制帧率了。否则在120hz刷新率的手机上vSyncCount=1会有120fps的帧率。直接使用targetFrameRate=30来设置帧率。
问题31: xLua开发Unity项目优化注意哪些事项?
1:扩展Unity的API,简化.localPosition等调用的交互次数。
尽可能的减少lua和C#的参数传递。比如通过扩展Unity接口,实现SetPosition直接给gameObject或者Component设置坐标,而不用 go.transform.position = xxx 这样设置坐标。
2:减少使用 os.date 函数。会有明显的内存分配。
3:在Update中频繁执行的代码,避免各种临时表的分配。
4:配表的内存优化。
5:使用 table.concat 组合字符串,而不是 … 连接。因为字符串每次 … 都会产生一份新的字符串内存。
6:尽可能避免数组:字典或者自定义类型的交互参数,这会产生大量的GCAlloc。如果是数组,可以考虑使用一个循环遍历调用。
7:尽可能避免lua到C#传递字符串参数。传递字符串操作不可避免的会有多份内存开销,C#需要把lua的字符串内存拷贝到托管堆中,这是性能低下且有GCAlloc的。
比如我们GetComponent获取类型,就统一使用type(CS.XXX)这样的类型做参数,而没有使用字符串获取组件。无论从交互的角度考虑,还是在C#内部获取组件的效率考虑,都会获得更好的性能。
问题32: Unity 常用的Shader优化技巧有哪些?
1:使用Mobile版本的shader。比如Particle/Additive中有ColorMask,这个在移动平台比较耗。
2:避免使用昂贵的数学函数。比如 pow exp log cos sin tan 等。
3:尽可能减少纹理采样数目。
4:如果有一些计算比较复杂,可以使用查找纹理(lut)
5:优先使用低精度的数字格式。优先使用half。在现代gpu上fixed等同于half。部分对精度有特殊需求的情况下才使用float。个别情况下,尤其是与法线相关的时候,使用half容易因为精度不足导致渲染结果错误,这个时候还是应该使用float。
问题33: Unity是左手坐标系还是右手坐标系?
Unity是左手坐标系,x正方向向右,y正方向向上,z正方向向屏幕里。
问题34: Unity绘制场景物体的渲染顺序是怎么样的?
1:不透明物体,离摄像机近的先绘制,这样它会因为ZTest剔除掉后面的渲染内容,性能更好。
2:半透明物体,必须从后往前画,先画离摄像机远的物体,才能保证渲染结果正确。
3:shader非常复杂的模型,尽量后绘制。比如T4M的地表shader,采样了七八张图纹理,那么它最后绘制,更加容易被Z-Culling剔除掉。
4:不透明物体(2000)----AlphaTest物体(2450)----半透明物体(3000),这个渲染顺序有利于HSR或者Early-Z的优化。Alpha-Test 在不透明物体绘制完毕之后再绘制,可以避免Alpha-Test导致EarlyZ失效,最后绘制,至少不会影响到之前不透明物体的EarlyZ。
5:RenderQueue2500,区分了不透明和半透明。半透明物体(2500以上)永远在不透明物体(2500以下)后绘制。如果物体的RenderQueue在2500的同一侧,则sortingOrder优先级更高:Camera Depth > Sorting Layer > Order In Layer > RenderQueue > 距离相机的距离。
问题35: Unity里Mipmap的理解有哪些优点与缺点?
优点:避免远处物体的锯齿或者闪烁感,效果表现更好。Texture Cache,纹理采样的缓存命中率上升,减少对显存的直接访问,减少带宽io,进而提高渲染效率。
缺点:多消耗了1/3的内存,增大包体积
问题36: Unity UGUI 优化RaycastTarget。
RaycastTarget勾选以后会消耗一些效率,为了节省效率就不要勾选它了,不仅Image组件Text组件也有这样的问题。 一般UI里也就是按钮才需要接收响应事件,那么大部分image和text是是不需要开RaycastTarget的。默认是选上的,记得关闭掉这些,可以提升性能。
问题37: Unity如何优化纹理图片的体积?
纹理图片的大小决定了包体的大小,我们要让包体小,需要优化纹理图片,纹理图片一般是由.png,jpg图片组成,我们可以通过压缩工具来压缩图片,一般我用的工具有TinyPNG。
问题38: Unity如何趴取游戏的资源?
Unity开发的游戏里面的资源可以被我们自己的项目所用,这里推荐一个工具,可以趴取Unity游戏包里面的3D模型,2D UI,字体,声音,甚至Shader都可以趴取出来,这个工具叫做AssetStudioGUI。
问题39: Unity 使用ILRuntime的优缺点
优点:语言(C#)\开发环境\工具链统一,随时可以变成不支持热更形式,如果苹果未来不允许任何解释执行的方式。框架搭好后,满足一些限制条件(非硬性限制,主要是避免麻烦,限制主要是1个,可热更部分的代码不要继承不可热更的代码, 不继承MonoBehaviour是这个限制的子集),写逻辑的同学开发方式和原生C#开发完全一样,包括调试。第三方插件直接可用(大部分插件都是基于C#写的)
缺点:稳定性的坑还是有一些:通常发生于一些相对高级的语言特性组合,特别是各种反射代码。另外.net4.6的async\wait所支持的现在版本应该也还不够稳定,纯计算的性能弱于Lua,计算密集型的代码还是想办法放在不可热更新的部分吧。
问题40: Unity是如何在IOS上打包的?
Unity 会先把C#编译成中间语言IL,利用IL2CPP把IL代码转成C代码,转完后在所有的代码都是C的项目和工程,再用xcode来编译这些代码。
问题41: 如何使用Unity来开发VR?
VR开发现在也非常的火,Unity也支持VR开发,我们一般如何做VR开发呢?我们拿到了VR的设备,每个设备一般针对Unity都会有VR的SDK,我们按照VR的SDK来创建一个项目就可以使用VR设备的API,以及使用普通的方式来开发Unity了,其实VR开发就是普通的Unity开发+VR的一些API接口。
问题42: Unity下有几种Lighting模式?
1:Baked Indirect,仅预先计算间接光照,不执行阴影预计算。阴影完全实时生成。所以远处没有阴影,近处是ShadowMap的阴影。
2:Shadowmask,烘焙间接光和阴影。动态模型和场景可以受实时方向光影响。即实时方向光可以改变场景色调。当选择为 Distance Shandowmask 之后,阴影光照图可以与实时阴影按照Shadow Distance设置的距离进行混合。近处显示实时阴影,远处显示ShadowMask。实时阴影更加清晰,Shadowmask受精度影响,效果不如实时阴影好。Shadowmask模式会将实时光和烘焙的光混合,同样可以混合实时阴影和烘焙的阴影。那么它就需要知道哪里是阴影,这个就需要 ShadowMask 图。
3:Subtractive,烘焙直接光照:间接光照和阴影。改变方向光不能影响场景。在此模式下,参与实时计算的只有动态物体的实时光照和动态物体对静态物体的投影。阴影直接被烘焙在lightmap上,所以不需要ShadowMask图。
问题43: Unity编写C#代码需要注意哪些地方?
1:不要使用foreach,每个foreach调用,大概会分配30B左右的内存.大量的调用会触发GC
2:尽量使用stringbuilder替代string.并且new stringbuilder(cap) 尽量预先分配好合适大小的内存.string.format的底层实现是stringbuilder,可以使用。
3:c#对于返回的变量,基本都是新new出来的.尽量少使用.比如
ICollection.ToArray(),会返回一个新new的T[]对象,ToString(),会产生string临时对象
4:不要使用Lambda表达式.每次都会有52B的内存分配. 定义函数替代之。
5:很多数据结构 比如list/Dictionary都提供了初始分配cap大小的构造函数.根据实际的需要,优先使用这样的构造函数来初始化数据结构
6:尽量不要使用值类型到System.Object的转换.c#俗称装箱.
7:不要以枚举/自定义struct作为Dictionary的key.尽量考虑用基础类型int等来替代。他们的GetHashCode都有装箱操作,每次调用TryGetValue查找都会有内存分配.
8:尽量减少new的次数,预分配/成员变量替代临时new变量等.
9:尽可能避免使用LINQ。部分功能无法在某些平台上使用,会分配大量GC Alloc。而且我很讨厌LINQ的一点就是它有可能在某些情况下无法很好的进行AOT编译。比如“OrderBy”会生成内部的泛型类“OrderedEnumerable”。这在AOT编译时是无法进行的,因为它只是在OrderBy的方法中才使用。所以如果你使用了OrderBy,那么在IOS平台上也许会报错。
10:尽可能避免使用delegate以及lambda。
问题44: Unity 内置的Shader函数定义实现在哪个地方?
Unity 为了方便大家开发Shader,定义了很多Shader的库函数,放到了. cginc文件里面,而这些.cginc的文件在Unity安装路径下,例如
C:\Program Files\Unity\Editor\2020.1.6f1c1\Editor\Data\CGIncludes
问题45: Unity 如何平滑过渡旋转?
有时候我们要控制角色模型从一个方向转到另外一个方向,如果两个方向之间的夹角比较大,那么转动起来比较生硬,我们可以通过四元数的球面插值来进行平滑处理,在update里面插值来达到平滑转向的目的。
问题46: Unity 四元数与欧拉角的优缺点?
Unity内部旋转计算,都是通过四元数来计算的。四元数计算旋转性能好速度快,并且能避免万向节锁的问题。但是四元数表示旋转不如欧拉角那么直观。欧拉角表示旋转比较直观,人类非常好理解,绕哪个轴旋转,欧拉角也可以转四元数,欧拉角有万向节锁的问题。
问题47: Unity 里面ECS开发模式是怎么样的?
Unity之前是组件化开发模式,现在提出新的开发模式ECS,E指的是Entity, C指的是ComponentData, S指的是System。多个ComponentData连续的排布在一起构成了实例Entity,把每种处理数据实例的逻辑编写成System,System的处理数据就是Entity, 这样的好处各Entity数据实例排布的更加紧密,数据实例里面不需要大量的引用数据类型hold住其他的实例, 性能更好。
问题48: Unity 人行动画有什么好处?
Unity 提出了人行动画,这个最大的好处是把Unity人行抽象成对应的骨骼,头,手,身体,脚等。当我们的动画特效人员基于这样的虚拟模型骨骼,调好了一个动画,那么其他的模型只要设置好对应的虚拟骨骼,就能使用这个动画,这样大大节约了调动画的时间,一组人行动画可以给多个角色来使用。
问题49: Unity 项目开发中 避免GC的常用技巧有哪些?
GC是一个非常高开销的系统调用也,是大部分卡顿的主要原因,不能完全控制。因此我们要尽量减少代码堆内存分配过量防止频繁触发GC,同时也可以在Loading或者对性能不敏感的时候主动GC。
升级高版本的Unity, 减少了lamda表达式的gc
减少一些字符串拼接,使用StringBuilder代替string减少GC开销
内存池:前面说过GameObject的内存池,另外还有类对象的内存池。所有频繁反复创建删除的都应该使用。两个用途,减少加载创建释放的时间,减少内存碎片降低GC的频率。
Unity接口:AddComponent,OnGUI,UI合并频率,delegate,等。
避免频繁创建开辟空间。
……
问题50; Unity 如何做断点调试?
Unity 做断点调试有两种方式,方式以使用Unity自带的开发工具MonoDevolop来进行调试。也可以安装visual studio for unity插件来结合VS来进行Unity断点调试。