Unity 客户端面试经验总结
用作个人备忘,内容过于简洁,不便于从零理解,如有错漏,欢迎指出。
=== Unity =================================
=== C# ===================================
=== Lua ==================================
模块与包
- Lua中的模块与包是用于组织和
封装
代码的重要机制。 - 模块是一个独立的
代码单元
,通常以.lua文件
的形式存在。 - 模块的
返回值
可以是一个表
,也可以是一个函数
。 - 包是模块的
集合
,用于实现更复杂的功能。 - 模块和包通常使用
require
关键字来加载执行。
require、dofile 和 loadfile,三者的区别:
- dofile,加载并
执行
; - loadfile,加载后返回一个函数对象,
不执行
; - require,加载并
执行
,与 dofile 不同点的在于:
require 有一个缓存
的机制,加载前会先确认文件是否已经加载过,如果加载过则直接执行。
dofile 无论文件是否加载过都会再加载一遍。
热更新机制
热更新,即在不停止服务器正常工作的情况下更新游戏代码逻辑或资源。
Lua 的热更新只能更新使用 Lua 编写的逻辑模块,依托 Unity 的 AssetBundle
将 .lua 文件打包实现。
xLua
开源库:https://github.com/Tencent/xLua/tree/master
xLua 为 Unity、.Net、Mono 等 C# 环境增加 Lua 脚本编程的能力,借助 xLua,这些 Lua 代码可以方便的和 C# 相互调用。
Table表
- 是一种强大的数据结构,底层由
数组和哈希表
实现。 - Table 的索引值(Key),可以是
整数
,也可以是字符串
。 - Table 可以当做数组使用,整数 Key 值作为数组索引,可以用
#
获取数组长度。 - 一个 Table 中每个元素的类型可以不同。
Table 常用方法:
- insert 插入
- remove 删除
- sort 排序
- concat 连接
ipairs 和 pairs 遍历 table 的区别:
- ipairs: 遍历至非整数索引时会停止遍历,因此只适合
遍历数组
。 - pairs: 遍历
所有
元素,即使遇到 nil,也会跳过并继续遍历。
数据类型
- nil: 空值。
- boolean: 布尔类型,ture 和 false。
- number: 数字,不区分整数和小数。
- string: 字符串,可以用单引号,双引号或
双中括号
包裹。 - function: 函数。
- table: 表。
- thread: 线程。
userdata:
用户自定义类型,存储 C 数据结构在 Lua 中使用。
元表与面向对象
元表(metatable)通过各种元方法定义了一个表的默认行为,通过使用元表和 __index
元方法可以模拟实现一个可继承的类及其子类:
-- 定义父类
local Dad = {}
function Dad:new()
local t = { value = 10 }
setmetatable(t, { __index = self })
return t
end
-- 为父类新建一个方法
function Dad:getValue()
return self.value
end
-- 定义子类
local Son = {}
function Son:new()
local t = Dad:new() -- 依托父类构建
setmetatable(t, { __index = Son })
return t
end
-- 重写父类方法
function Son:getValue()
return self.value * 2
end
-- 创建子类实例并调用
local instance = Son:new()
print(instance:getValue()) -- 输出20
点号和冒号的区别:
点号 .
调用方法时不会传递 self 参数,除非显式传递;冒号 :
调用方法时会自动传递 self 参数。
两个点和三个点的意义:
双点 ..
是连接符,用于连接两个字符串;三点 ...
代表可变参数。
元方法
- 运算符重载:加法 +
__add
,减法 -__sub
,乘法 *__mul
,除法 /__div
,取模 %__mod
,幂 ^__pow
,连接..
__concat
,相等 ==__eq
,小于 <__lt
,小于等于 <=__le
。 - 外部调用:
__call
把表作为函数调用时触发;__tostring
把表作为字符串调用时触发。 - __index:
访问
表中不存在的键时触发。 - __newindex: 为表中不存在的键
赋值
时触发。 - __metatable: 用于
保护
元表,防止外部访问或修改元表。
local 变量与闭包
Lua 中的变量不需要显式的声明类型,而是通过右值动态确定变量类型,不使用任何关键声明的变量都是全局变量;
使用 local 关键字声明的变量即为 局部变量
。
闭包是由函数和其相关联的引用环境组合而成的实体。
一个函数可以创建多个闭包,通过闭包机制,函数可以使用外部的局部变量执行逻辑,这些被函数捕获的外部变量被称为 upvalue
。
内存管理与GC
Lua 通过 引用计数
的方式来管理内存,通过 标记 - 清除
的方式自动管理垃圾的回收。
也可以通过 GC方法调用
的方式来手动控制GC的运作,例如,改变GC的频率和搜索步长,重启和关闭GC等。
C与Lua互相调用
- C中调用Lua:添加Lua头文件,创建Lua状态机,加载并执行Lua脚本。
- Lua中调用C:先在Lua中注册C函数,然后在Lua中执行注册了C函数的方法。