Unity Lua方向的面试真题详解

最近有位同学面试Unity,面试的公司采用Lua的方案来做公司项目,我们把面试时问道的真题列举出来,并配上参考回复。

1、Lua热更文件时,文件是重写的,还是只写一部分?

热更分为资源更新和代码更新,资源更新的颗粒度是基于ab包的,是基于一个个资源包来进行下载和替换。做代码热更新的时候,如果热更代码被打入了ab包,那么下载的时候,也是整个代码所在的ab包一起下载。如果热更代码是单独部署的,我们就可以基于对应的文件颗粒度来下载替换。一般做lua热更新的时候,代码打成ab包后,可能只有几百k,并不很大,那么我们打一个ab包就可以了。如果lua代码打包成ab包后很大,我们可以考虑把lua代码分成几个ab包,这样下次热更的时候,就是基于lua代码所在的ab包来热更。对于其它热更技术也类似。热更代码是打一个ab包,还是打多个ab包,完全取决于代码ab包的大小;

2: lua是怎么热更的?

step1:lua做热更时,通过版本对比,md5文件差异比较,把更新的lua代码所在的ab包下载下来;

step2: 当最新代码下载下来以后,我们首先去下载目录下加载lua代码所在的ab包,如果没有,就到本地StreammingAssets目录下加载,如果没有,就报错。

step3: Lua 虚拟机添加 customloader, 当有require来加载lua代码的时候,我们就从来到 customloader的函数,这个函数从Lua代码所在的ab包里面,根据

lua文件路径,把文本资源读出出来,并装载到lua虚拟机里面执行。

由于每次都是优先从下载目录下加载lua, ab包,所以热更的时候,能加载执行到最新代码。

3:Lua语言中 require的顺序是怎样的

step1:这个是require的语法,首先是lua虚拟机从文件中读取lua代码,

step2: 把lua代码装在进lua虚拟机;

step3: 执行lua代码里面的代码指令和函数调用;

step4: 如果有return, 返回结果;

step5: 如果重复require, 就只会执行里面的函数调用与代码指令,不会反复的装载;

4、说说lua的传值与传引用

lua分成基本的数据类型和引用对象数据类型:

字符串,表,数组,属于引用类型,变量保存的是它对象的引用,我们通过引用访问它;

数字,bool值等基本数据类型,变量直接存储他们的数据;

对于基本数据类型而言,赋值语句就是数据copy;

对于引用数据类型而言,赋值语句,就是让这两个变量指向同一个内存对象;

5: 垃圾回收机制(C# Lua)

Lua虚拟机内置了自己的垃圾回收机制和接口,我们在封装lua虚拟机的时候,需要在特定的时候,来调用,Lua的gc接口来回收相关的垃圾,一般我们会在Lua虚拟机封装的时候,在c# 的update里面,设定一些lua垃圾回收的触发条件,比如,每隔100ms调用一次gc, 回收一次等,具体的策略,可以根据实际情况来定。同时lua可以允许开发者自己在特定的时机来调用垃圾回收。

7、垃圾回收造成卡顿,怎么办

当某个时候,有大量的垃圾需要回收的时候,会由于gc所造成卡顿。这个时候,我们能做的就是回收一部分,另外的部分后面去回收,将gc回收的时机,不断地延后,平均到某个update里面,使得过度地时候帧率更加地平滑。这个时候我们需要留意在GC高峰期,来做一些事情,比如,场景地图切换地时候,这个时候容易引发gc高峰,时刻监测,如果发现切换高峰地时候GC造成的卡顿,我们就可以按照上面的思路来处理,主要是减少每次GC的量,延迟GC到后面的update,避免波峰的冲击。

8:说说你们项目中的战斗系统的架构与设计:

做战斗系统和架构的时候,我们一般把代码逻辑分成3层来设计,同时把数据独立出来,我们的项目设计如下,不同公司可能不一样,我们之前公司是这样做的:

1: 我们会把战斗中的功能,做成组件,比如,动画切换,伤害计算等; 我们叫做功能层;

2: 我们会把战斗单元做一个组件,比如Charactor, 然后让Charactor来has 功能组件,并在Charactor中提供标准的通用的策略,比如,行走,技能释放等; 同时不是的角色,我们会编写Player, Enemy等来继承自Charactor,并绑定对应角色的战斗数据,用战斗数据来驱动统一的逻辑;

3: 操作层:我们会把战斗中的操作独立出来,比如UI操作,网络事件,AI事件等,通过事件模块,来调用到战斗中的具体策略,这样,可以实现不同操作层来驱动战斗,调用战斗策略;

4: 战斗中的数据,我们一般都用excel表格来给策划填写,更具策划的游戏需求来制定好对应的数据格式。如果有必要,还可以做一些可视化工具(技能编辑器),来给策划使用,最后导出战斗数据。

5: 技能编辑器:可视化的制定技能的一些数据,比如buff时间,攻击时间,等具体要根据游戏需求来定;

9: 说说项目中网络同步,延迟问题 如何解决的?

网络同步 延迟问题 是做网络游戏开发中比较经典的问题,要考虑这个问题,我们首先要搞清楚,我们的游戏同步采用的是帧同步还是状态同步。

如果游戏是状态同步,那么要解决网络延时问题,只能通过传输来解决,一般用可靠的UDP来做,比如kcp等。减少网络延时,和网络波对对游戏的体验。由于状态同步是服务端跑逻辑,客户端根据状态来展示,所以除了底层通过可靠UDP来减少网络延时以外,没有其它的办法。

如果是帧同步,每一帧,服务端会把所有客户端的操作转发出去,这个时候要解决网络延时问题,也是用UDP来代替传统的TCP,来做数据通讯,如果某个数据包卡住的情况下,客户端,可以用上一帧的操作,延长几帧的处理时间,做所谓的"预演",如果下一帧来的操作,刚好和上一帧一样,那么预演成功,客户端感觉不出来卡顿,不成功,客户端会卡顿or鬼畜。

10: 帧同步要注意哪些点?

铲屎官,你好,关于帧同步要注意哪些点,我这边总结如下:

1: 首先要注意点就是什么样的游戏,能采用帧同步。

a: 同一局游戏,对战的玩家的数目是有限的,一般小于 < 50人左右,比如MMORPG,这种就不适合帧同步;

b: 如果一局游戏,很长时间无法结束,那么不能使用帧同步,比如MMORPG这种一直可以玩没有结束的游戏这种不适合帧同步;

2: 接下来帧同步要解决的问题就是通讯选择,目前主流的做法是TCP/UPD/可靠UDP(如kcp等),帧同步有用TCP, 有用UDP,也有用可靠UDP的,具体可以根据团队的技术能力,技术积累,游戏的发布平台等综合考虑。比如,H5,我们大概率会采用TCP作为帧同步。如果是做手机游戏,可以考虑用UDP,kcp等,有些运营的平台不允许用UDP,只能用TCP,所以在做项目之前要综合考虑好。UDP确实有更好的体验,但是TCP,部署安全等,会更方便。

3: 帧同步服务端的广播频率的选择,15~20FPS左右,一般常见的事件广播频率。

4: 帧同步确定性的选择,包括定点数,随机数,根据自己的游戏类型,提前确定好所需要做确定性的代码库,比如确定性无力引擎,确定性的RVO等。

最后可能不同的项目还会有具体要注意的点,这个需要具体项目具体分析。

相关推荐
yaoh.wang1 小时前
力扣(LeetCode) 111: 二叉树的最小深度 - 解法思路
python·程序人生·算法·leetcode·面试·职场和发展·深度优先
沐雪架构师2 小时前
大模型Agent面试精选题(第六辑)-Agent工程实践
面试·职场和发展
Dolphin_海豚2 小时前
到底是选 merge 还是选 rebase
git·面试·程序员
老朱佩琪!2 小时前
Unity备忘录模式
java·unity·备忘录模式
不想秃头的程序员2 小时前
JS原型链详解
前端·面试
努力学算法的蒟蒻2 小时前
day42(12.23)——leetcode面试经典150
算法·leetcode·面试
一帘多啦A梦3 小时前
解决unity2022.3.x版本项目使用vs无法生成解决方案的问题
unity·vs
不想秃头的程序员3 小时前
JS继承方式详解
前端·面试
摇滚侠4 小时前
面试实战 问题三十五 Spring bean 的自动装配 介绍一下熟悉的几种设计模式 Java 四种线程池是哪些
java·spring·面试
沐雪架构师5 小时前
大模型Agent面试精选题(第五辑)-Agent提示词工程
java·面试·职场和发展