Unity游戏开发客户端Lua基础

本文是关于Unity游戏开发中Lua初级面试的知识点总结,包括pairs与ipairs的区别、点与冒号的不同、面向对象实现、_index与_newindex、_rawset与_rawget、只读表的创建、Table、string类型、lua的GC算法以及C#与xlua交互的原理等。同时,讨论了Lua与C#的交互、类型系统、循环、闭包及其作用,深入探讨了lua如何实现C#委托功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:记录了总6w字的知识点,文章中的知识点若想深入了解,可以点击链接学习。由于文本太多,按类型分开。这一篇是lua常问问题总结,有帮助的可以收藏。


1.pairs与ipairs区别

        两者都是用迭代器实现

pairs:

        pairs会遍历所有key,对于key的类型没有要求,遇到nil时可以跳过,不会影响后面的遍历,既可以遍历数组部分,又能遍历哈希部分,但是不保证遍历顺序,因为Lua的表是无序的

         源码解析:
function pairs(t)
    return next, t, nil
end

   pairs 是一个更通用的迭代器生成器,用于遍历表中的所有键值对。它利用了Lua的内置函数 next,该函数会返回表中下一个键值对。

  • pairs 返回三个值:next 函数、表 t 和初始键 nil
  • next 函数会从表中返回下一个键值对,直到没有更多的键值对。

ipairs:

        ipairs只会从1开始,步进1,只能遍历数组部分, 中间不是数字的key忽略, 到第一个不连续的数字为止(不含),遍历时只能取key为整数值,遇到nil时终止遍历。

     源码解析:
function ipairs(t)
    return function(t, i)
        i = i + 1
        local v = t[i]
        if v == nil then
            return nil, nil
        end
        return i, v
    end, t, 0
end
  • 这个实现中,ipairs 返回一个迭代器函数、表 t 和初始索引 0

  • 迭代器函数每次调用时,会将索引 i 加1,并检查表中该索引的值是否为 nil。如果值为 nil,则停止迭代。

local t2 = { 1, 2, [3] = 10, 3, 4}

for i, v in ipairs(t2) do
    print(i, v)
end

Output:

1    1
2    2
3    3
4    4

(在Lua中,表是基于哈希表的,这意味着它们可以存储任何类型的键,而不仅仅是整数。当你使用非连续的索引(如[3] = 10)时,Lua会将这些索引转换为哈希键,以便在表中存储和检索对应的值。)

2.点和冒号区别

区别:

   参数传递:

        点  :用于访问表中的字段或调用表里的函数,不绑定任何特定的上下文对象;调用时,不会自动传递任何参数,如果需要传递参数,必须明确指定。不一定要传递self,根据需求传递,包括但不限于:table,string,function,number,boolean,thread,nil。传递的参数为方法里面的self。

        冒号 :用于调用表中的方法,并且会自动将表本身作为第一个参数对下传给该方法。调用时,会自动将表本身作为第一个参数传递给方法。

   调用时机

        点:适用于访问表的字段或者调用普通函数,不涉及上下文。

    冒号:调用一个方法,并且该方法需要访问对象的字段或状态。

       

3.Lua如何实现面向对象

继承:

        Lua面向对象编程是基于元表metatable,元方法__index来实现的。

        通过元表的__index元方法,将一个table的__index元方法设置为另一个table,那么后者的方法就被前者继承。

        如果访问了lua表中不存在的元素时,就会触发lua的一套查找机制,也是凭借这个机制,才能够实现面向对象的。

        总结元表的查找步骤:

        在表中查找该元素,如果找到,返回该元素,找不到则判断该表是否有元表(setmetatable(A,B)     -- 把 B设为 A的元表 ),如果没有元表,返回nil,有元表则判断元表有没有__index方法不是直接看元表有该元素!),如果__index方法为nil,则返回nil;如果__index方法是一个表,则重复上述步骤;如果__index方法是一个函数,则调用该函数,并返回该函数的返回值。

封装:

        1.lua的表可以同时存储数据和函数,可以实现简单的封装。

        2.闭包隐藏内部状态,只暴露了必要接口,也实现了封装。

        3.通过元表实现类的封装,可以模拟面向对象编程,支持继承。

        4.将相关函数和数据封装在一个模块中,通过模块接口对外提供服务,便于复用和管理。

多态:

        多态本质也是通过元表和表的机制来模拟多态的行为。

        1.动态绑定:将利用元表的__index方法指定一个表后,有了继承关系,重写了父类里面的函数。

        2.方法重载:根据传参类型不同,执行不同的逻辑。

 4.__index 与 __newindex的区别     

     注意:__index 和__newindex归为元表方法。

  __index:

        当子脚本不存在被访问的元素的时候,lua就会调用__index,去父脚本里面查找该元素。

            参数:

                如果__index是一个函数,那么参数是:table:被访问的表;key:被访问的键。

                如果__index是一个表,Lua会在这个表里面查找key对应的值。

  __newindex:

        当赋值时,如果赋值一个不存在的索引。

        如果__newindex是一个表,那么会把这个值赋值到newindex所指的表中(有这个索引就修改,没有就创建),不会修改自己;

        如果__newindex是一个函数,那么会调用这个函数。

            参数:        

       table:被赋值的表。

       key:被赋值的键。

       value:被赋值的值。

代码:

        1.__newindex指定一个函数

        2.__newindex指向一个空表

### Unity3D 客户端开发试常见问题及解答 #### 1. 如何在Unity3D中查看场景的数、顶点数和Draw Call数? 为了监控性能,在Unity编辑器中可以启用统计信息板来查看这些数据。通过菜单栏中的`Window -> Analysis -> Profiler`打开Profiler窗口,切换到CPU Usage标签页下的Rendering部分可看到详细的渲染统计数据[^2]。 ```csharp // 使用代码获取当前帧绘制调用次数 int drawCallCount = UnityEngine.Rendering.DrawCallsPerFrame; Debug.Log($"Current Draw Calls: {drawCallCount}"); ``` #### 2. 怎样减少Draw Call数量? 降低Draw Call的有效方法包括但不限于: - **批处理**:确保网格尽可能共享材质并开启静态/动态批处理选项。 - **LOD (Level of Detail)**技术的应用。 - 减少透明度排序开销高的物体数目。 - 合理利用Sprite Atlas纹理图集功能。 - 将多个Mesh合并成单个更复杂的模型以减少独立渲染指令的数量。 #### 3. ipairs函数的作用是什么? `ipairs` 是Lua语言里的迭代工具,专门用来遍历具有连续整型键值对的数据结构(即数组)。它会按照升序访问从索引1开始直到遇到首个nil为止的所有元素[^3]。虽然这是针对Lua环境描述的功能特性,但在理解表格(Table)操作逻辑方同样适用。 #### 4. 判断一个Table是否为空的方法有哪些? 对于判断表是否为空的操作,可以通过检查其长度属性(`table.getn`)或是尝试读取任意成员变量来进行验证;另外也可以借助于全局辅助库提供的API实现这一目的。然而需要注意的是,在某些情况下即使存在未定义项也可能被误判为非空状态,因此最好结合实际情况灵活选用检测手段。 ```lua -- 方法一:直接计数法 function IsEmpty(tbl) local count = 0 for _ in pairs(tbl) do count = count + 1 end return count == 0 end -- 方法二:使用next()内建函数 function IsEmpty(tbl) return next(tbl) == nil end ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值