Unity常考题目

1.生命周期

Awake()
OnEnable()
Start()
Update()
LateUpdate()
OnGUI()
OnApplicationQuit()
OnDisable()
OnDestroy()

2.碰撞和触发

unity检测碰撞条件:
双方都要有碰撞器,一方有刚体就能发生碰撞

碰撞和触发是碰撞检测两种方式,一种是利用碰撞器,另一种则是利用触发器。
碰撞器与触发器的区别:
碰撞有碰撞效果,触发没有碰撞效果
使用触发器时,碰撞器根据物理引擎引发碰撞,产生碰撞的效果;
不使用时,碰撞器被物理引擎所忽略,没有碰撞效果。

3.内存泄露排查方式:

(1)
使用泄漏追踪工具。
腾讯的Cube
UWA
Memery profile unity5
用来检测项目在运行时,各各资源在内存的使用情况,所占大小引用次数
怎么处理:
1:常使用的对象,尽量使用对象池
2:对象及时销毁
3:尽量在需要的时候,申请有限空间
4:代码规范
5: 数组如果不需要时,一定要清0,

4.程序的优化

(1)怎么优化:
在优化Unity游戏时,我们一般从四个方面:CPU、GPU、内存、工程配置等入手,它们都可能是影响游戏性能瓶颈的关键
①压缩自带类库;
②运用对象池;
③释放AssetBundle占用的资源;
④降低模型的片面数,降低模型的骨骼数量,降低贴图的大小;
⑤使用光照贴图(烘焙),使用多层次细节(LOD),使用着色器(Shader),使用预设(Prefab)。

(2)UI(图集使用和网格重建带来的影响)使用图集、动静分离
1)引起Canvas对网格的重建大概有几种情况Image,Text等UI元素的Enable及UI元素的长、宽或Color属性的变化等。因此在一些较复杂的界面,可以多分几个Canvas出来,虽然会增加drawcall,但是减少了网格重建时间,让性能有更好的提升。
2)摇杆区,技能区,血条,经验条是比较容易变化的,把这些都放到一个叫Dynamic的节点,并有自己的canvas,这样在他们频繁变化时,也只需要对这小部分进行网格重建,相对于整个MainUI重建的开销就小非常多了

(2)场景(光照、烘焙、相机后期处理)
1)若不用光肯定是最快的。移动端优化可以采用用光照贴图(Lightmapping)去烘培一个静态的贴图,以代替每次的光照计算,在U3D中只需要非常短的时间则能生成。这个方法能大大提高效率,而且有着更好的表现效果(平滑过渡处理,还有附加阴影等)。
2)自动和并考虑和静态批处理(Batching Static网上文章较多)
3)相机后期处理,可以考虑分级处理高端机使用
4)高低模切换,远景视距模型切换,还有很多可动态调整增强性能的保障

(3)高低适配
1)分辨率、高低模、阴影效果、环境光

资源加载

1.对资源加载有什么看法。
首先资源加载这个东西,就是老大难,用户一遍遍的吐槽加载的慢,但是谁也不愿意让加载的少导致后边必须加载而变得卡顿。对于比较耗费的加载,属于IO操作,在游戏刚登陆的时候,进行初始化加载。强制加载一些重要模块,比如登陆窗口(用户输入用户名密码的地方)等等。选择性加载一些必要的模块:如果这人需要新手引导,则加载新手引导模块,否则不加载,反之亦然。这些用户一定会用(或者一定不用)的模块,在登陆时候处理好。
对于应用模块:比如我打开一个很庞大的UI,这个怎么加载,如果这个模块很吸金,用户用得概率很大,那么必须在登陆时加载,否则那只能用户打开的时候加载了,加载的时候要转圈提示用户。关于场景加载更加的莫衷一是。既然大家被面到这一步了,相信也不需要我废话了,一个程序有一个程序的活法不是吗?

动态更新

1.答:这个题牵扯到assetbundle问题。其中assetbundle面对资源的处理方法是截然不同的。比如对于prefab,可以很好的搞上去,对于二进制文件,也能搞得不错,但是对于代码这个东西,往往是大家争论的焦点——毕竟代码这个东西,iosAppStore是肯定不让你搞得,因为unity本身也不受苹果待见,所以它怕被秒杀,也不给用户提供更新脚本的功能。这就导致比如你更新了一个prefab,没法使用它上边挂的脚本!提供一下解决代码更新的一点看法,现在我再尝试搞这一块,一孔之见,轻喷
2.安卓上可以使用unityreflaction机制进行编译后代码的动态更新,这个广大google开发者肯定是知道的。但是问题就是,这种机制会导致很庞大的开发成本——从代码层面完全跟ios搞了个大分支,如果是想跨平台的,这恐怕是不可取的吧。。
3.第二就是可以采用lua脚本无缝编写方法,因为unity脚本并不是真正的脚本,真正脚本的威力是它可以动态编译到宿主上,这点太牛逼了。lua就是这种牛逼脚本。所以你可以无缝换lua。这个没问题。所以立项就应该想好是lua还是什么的。别回来做了一半,想改lua了。
这两种机制在App Store上肯定是不让你搞的,第一种,越狱平台也不让搞,因为unity不让你搞。

Lua的数据类型

8种
string 字符串,一旦赋值不能被修改,可以通过方法string.gsub()来修改
nil 全局变量没被赋值默认为nil,删除变量就赋值为 nil
Boolean bool false 和nil为假 ,其它都为真
function 函数
table 数组、容器
number 实数 ,可以是整数,浮点数
thread 线程
userdata (类,其它语言转换过来就变成userdata类型)

Lua热更原理:

2.lua怎么做热更新
lua的执行依赖于其解释器,通常来说就是lua.c中的代码。lua在unity中作为一个文本资源来使用,当我们通过tolua或者xlua调用lua代码中某个函数时,解释器会去对lua进行解释,因为lua解释器代码允许执行,因此它会执行lua解释后的代码。
好处:
可以在程序运行时,直接更新项目资源。不需要重新发布,防止玩家流失

基本就是游戏玩法的代码。网络、资源加载等基础模块一般不会变,所有很多都是用C#写的。说白了,不变的代码用C#写更高效,变化的代码用lua写。
打包和lua唯一的关系就是lua代码文件作为资源被打包。

ab包

AssetBundle.Unload(false):释放AssetBundle文件内存镜像
AssetBundle.Unload(true):释放AssetBundle文件内存镜像同时销毁所有已经Load的Assets内存对象

实际运行过程中会出现用AssetBundle.Unload(false),但是加载的内容没有显示出来,导致这种问题的原因是U3D没有处理好的一个环节。在WWW加载资源完毕后,立刻对其资源进行unload,然后再进行Instantiate,此时进行unload会对资源造成影响,以至于Instantiate没有贴图或者等等问题发生。

解决办法:
先进行Instantiate, 再AssetBundle.Unload,或者自己写个时间等待功能,等待1到2帧之后再进行Unload。这样就不会出现Instantiate渲染中就运行unload的情况了。

socket

Unity socket

Socket译为套接字,支持TCP/IP协议网络通信的基本操作单元,可以将套接字看做不同主机间的进程双向通信的端点。

Socket的通信流程

(1) 开启一个连接之前,需要新创建一个socket,然后将地址和端口绑定给这个sockrt,客户端在调用connect的时候,会由系统自动分配端口,因此可以省去bind

(2) 服务器开启监听

(3) 客户端连接服务器,服务器通过accept接收客户端连接

(4) 客户端和服务器通过write和read发送和接收数据

(5) 通过close关闭连接

你可能感兴趣的:(unity)