激情六月丁香婷婷|亚洲色图AV二区|丝袜AV日韩AV|久草视频在线分类|伊人九九精品视频|国产精品一级电影|久草视频在线99|在线看的av网址|伊人99精品无码|午夜无码视频在线

高校合作1:010-59833514 ?咨詢電話:400-810-1418 服務(wù)與監(jiān)督電話:400-810-1418轉(zhuǎn)接2

unity3d開發(fā)教程-lua入門

發(fā)布時(shí)間:2024-04-08 09:23:19 瀏覽量:143次

如果你還沒有編程基礎(chǔ),建議你先學(xué)習(xí)一些編程基礎(chǔ)。本文不是完全菜鳥教程,主要針對(duì)有其他語言經(jīng)驗(yàn)的開發(fā)者,如果想看菜鳥教程,建議看菜鳥教程的 Lua教程。

先看一個(gè)簡單類的代碼

  1 ---@class BsnsPack @Base class of business pack
  2 local BsnsPack = {
  3     -- class fields
  4     maxSerialNo = 0,
  5 }
  6 
  7 BsnsPack.__index = BsnsPack
  8 
  9 --- new()
 10 ---@return BsnsPack
 11 function BsnsPack.new()
 12     local o = {}
 13 
 14     -- member fields
 15     o.serialNo = 0
 16     o.mod = 0
 17     o.cmd = 0
 18     o.payload = nil
 19     
 20     -- bind BsnsPack methods
 21     setmetatable(o, BsnsPack)
 22     return o
 23 end
 24 
 25 --- set serial No.
 26 ---@param serialNo number
 27 function BsnsPack:setSerialNo(serialNo)
 28     self.serialNo = serialNo
 29 end
 30 
 31 --- get serial No.
 32 ---@return number
 33 function BsnsPack:getSerialNo()
 34     return self.serialNo
 35 end
 36 
 37 --- set mod
 38 ---@param mod number
 39 function BsnsPack:setMod(mod)
 40     self.mod = mod
 41 end
 42 
 43 --- get mod
 44 ---@return number
 45 function BsnsPack:getMod()
 46     return self.mod
 47 end
 48 
 49 --- set cmd
 50 ---@param cmd number
 51 function BsnsPack:setCmd(cmd)
 52     self.cmd = cmd
 53 end
 54 
 55 --- get cmd
 56 ---@return number
 57 function BsnsPack:getCmd()
 58     return self.cmd
 59 end
 60 
 61 --- set payload
 62 ---@param payload any
 63 function BsnsPack:setPayload(payload)
 64     self.payload = payload
 65 end
 66 
 67 --- get payload
 68 ---@return any
 69 function BsnsPack:getPayload()
 70     return self.payload
 71 end
 72 
 73 function BsnsPack.test()
 74     print(BsnsPack.serialNo)
 75 end
 76 
 77 --- testPrivate
 78 ---@param self BsnsPack
 79 local function testPrivate(self)
 80     print(self.serialNo)
 81 end
 82 
 83 ---@alias Request BsnsPack @Request is BsnsPack
 84 local Request = BsnsPack
 85 
 86 ---@class Response : BsnsPack @Response class
 87 local Response = {}
 88 setmetatable(Response, BsnsPack) -- bind super methods
 89 Response.__index = Response
 90 
 91 --- new()
 92 ---@return Response
 93 function Response.new()
 94     local o = BsnsPack.new()
 95 
 96     -- member fields
 97     o.code = 0
 98 
 99     setmetatable(o, nil) -- remove original metatable
100     setmetatable(o, Response) -- bind Response methods
101     return o
102 end
103 
104 --- get result code
105 ---@return number
106 function Response:getCode()
107     return self.code
108 end
109 
110 local bsnsPack = {}
111 bsnsPack.BsnsPack = BsnsPack
112 bsnsPack.Request = Request
113 bsnsPack.Response = Response
114 
115 return bsnsPack

1、第1行:這是一行注釋

Lua的行注釋以兩個(gè)減號(hào) -- 開頭,

class注解:---@class TYPE[: PARENT_TYPE {, PARENT_TYPE}] [@comment]

這樣有利于 VS Code 代碼提示,例如將鼠標(biāo)放到代碼中出現(xiàn) BsnsPack 的地方上,會(huì)有小彈窗提示這個(gè)table的key,以及key的類型。

用得比較多的注解有 ---@class,---@return,---@param

2、第2行,定義一個(gè)叫 BsnsPack 的class(通過table模擬)。

Lua里沒有類,Lua的結(jié)構(gòu)化數(shù)據(jù)類型叫table,基于key-value結(jié)構(gòu)。相對(duì)于其他語言的 map / dictionary。訪問一個(gè)table的key對(duì)應(yīng)的值,可以用點(diǎn) . 來訪問,也可以用中括號(hào)[]來訪問

Lua里沒有單獨(dú)的數(shù)組結(jié)構(gòu),也是基于table,數(shù)組下標(biāo)是key,數(shù)組元素是value,要注意的是,Lua里數(shù)組下標(biāo)是從1開始的。

創(chuàng)建table的最簡單方式就是花括號(hào) {},創(chuàng)建一個(gè)空table。

Lua是腳本語言,變量不需要指定類型,只需要給它賦值。所以 BsnsPack = {maxSerialNo = 0,} 相當(dāng)于定義了個(gè)變量 BsnsPack,它的值是一個(gè)table。

Lua的變量默認(rèn)是全局的,加載到內(nèi)存的Lua代碼都可以訪問這個(gè)變量。為了避免命名沖突和意外修改,一般建議變量定義為局部變量,限制它的作用域。在變量前面加個(gè) local定義局部變量。

這里定義的 BsnsPack ,作用域只在這個(gè)文件里。其他文件不能訪問。也可以在函數(shù)、代碼塊里用 local 定義局部變量。

3、第7行,給 BsnsPack一個(gè)叫 __index 的 key 賦值為 BsnsPack 自己

Lua 的 table 里,__index 是個(gè)特殊的key,這是 Lua實(shí)現(xiàn)類和繼承的關(guān)鍵。

Lua里有個(gè)概念叫做元表。Lua定義了一些語言默認(rèn)key,這些key一般跟 +、-、*、/等操作符、key的訪問、值更新關(guān)聯(lián),這些key叫做元方法(Lua里的函數(shù)/方法也可以作為值),這些元方法合起來叫元表。

Lua里設(shè)置元表的方法是代碼第 21 行的 function setmetatable(t, metatable),調(diào)用這個(gè)方法會(huì)讓參數(shù) metatable 成為 參數(shù) t 的元表。

設(shè)置元表后,在代碼里訪問參數(shù) t 的一個(gè)key時(shí)會(huì)發(fā)生以下情況:

1)Lua先在 t 里找,看有沒有這個(gè)key,如果有,就返回這個(gè)key的值。否則,執(zhí)行2)

2)Lua看參數(shù) metatable 有沒有 __index 這個(gè)key,如果有,就在 __index 對(duì)應(yīng)的值里查找(__index的值如果是表,在這個(gè)表里查找;如果是函數(shù),執(zhí)行這個(gè)函數(shù))

BsnsPack.__index = BsnsPack,如果其他的table設(shè)置 BsnsPack 為元表,就可以訪問 BsnsPack 所有的key。 這些key的值如果是方法,就可以調(diào)用這些方法。

所以 BsnsPack 可以定義方法的模板,這就跟class類似。BsnsPack定義的數(shù)據(jù)key,相當(dāng)于靜態(tài)字段class field。BsnsPack定義的方法key,可以是成員方法member method,也可以是class method,后面介紹

4、第11~23行,定義BsnsPack的一個(gè)叫new的key,它的值是一個(gè)方法

Lua里一個(gè)代碼塊不用花括號(hào){},通過end作為結(jié)束標(biāo)記。

定義方法用 function 開頭,用點(diǎn).或者冒號(hào):分割talbe名和方法名,

用冒號(hào):定義的方法,會(huì)有個(gè)默認(rèn)參數(shù)self,相當(dāng)于調(diào)用者,如果外部用 BsnsPack:new() 這樣調(diào)用,則self == BsnsPack,如果用a:new()這樣調(diào)用,self==a。

用點(diǎn).定義的方法,沒有默認(rèn)參數(shù),只能顯式寫參數(shù)self。

一般地,用冒號(hào):定義成員方法member method(例如第23行的 function BsnsPack:setSerialNo(serialNo) )

1)調(diào)用 o:setSerialNo(serialNo) 時(shí),這里的self是對(duì)象o,只改對(duì)象o的serialNo,其他對(duì)象的serialNo不受影響。

用點(diǎn).定義構(gòu)造對(duì)象的方法(例如第11行的 function BsnsPack.new()),以及靜態(tài)方法class method(例如第69行的 function BsnsPack.test() )

1)在其他地方通過 BsnsPack.new()構(gòu)造BsnsPack對(duì)象

1)在其他地方通過 BsnsPack.test()調(diào)用類方法

建議,方法定義的時(shí)候是冒號(hào):,調(diào)用的時(shí)候用冒號(hào):,定義的時(shí)候是點(diǎn).,調(diào)用的時(shí)候也用點(diǎn).

構(gòu)造方法不一定叫new,只是為了統(tǒng)一,建議都用new,與其他語言一致。

方法new里面的 local o = {},定義的key都是成員字段member field(每次調(diào)用方法 BsnsPack.new() 都創(chuàng)建一個(gè)新的 table并對(duì)其字段初始化后返回)

Lua沒有私有的成員方法,可以定義文件的 local 方法,把對(duì)象作為參數(shù)self顯式的傳進(jìn)去(例如第79行 local function testPrivate(self))

5、第84行,給類BsnsPack定義一個(gè)別名 Request,其實(shí)就是把一個(gè)table賦值給另外一個(gè)變量

6、第87~102行,定義一個(gè)類Response,繼承基類BsnsPack

第87行,定義子類Response

第88行,設(shè)置元表,使得Response可以訪問BsnsPack所有的key(繼承BsnsPack所有的方法)

第89行,所有對(duì)象可以訪問Response所有的key(通過遞歸,包括BsnsPack所有的key)

第94行,通過調(diào)用BsnsPack構(gòu)造方法初始化o,o是BsnsPack的對(duì)象,擁有基類所有的member field

第97行,定義Response相對(duì)于基類新增的字段code

第99、100行,修改o的元表為Response,這樣o可以訪問Response所有的成員方法 member method(通過遞歸,包括BsnsPack所有的成員方法)

Response可以重寫B(tài)snsPack的方法

1 function Response:getPayload()
2     return self.payload
3 end

由于Lua里訪問key,先在table本身查找,如果沒有才在元表查找,所以會(huì)調(diào)用重寫的方法,實(shí)現(xiàn)多態(tài)。

7、第110~115行,導(dǎo)出本文件定義的類。

由于class的定義都是以 local 方式定義的局部變量,外部不能訪問,所以要把它當(dāng)作文件的返回值 return

如果該文件只導(dǎo)出一個(gè)class,直接return這個(gè)局部變量就可以,(例如,如果只導(dǎo)出BsnsPack,return BsnsPack 就可以)

由于本文件需要導(dǎo)出3個(gè)class,這里把他們放到一個(gè)table里導(dǎo)出

其他文件需要訪問這個(gè)文件的class,需要調(diào)用require方法導(dǎo)入進(jìn)來,該方法的參數(shù)是路徑(不含后綴.lua),返回值是這個(gè)lua文件的return值

1 local bsnsPack = require("Assets.Lua.bsns.bsns_pack")
2 local Request = bsnsPack.Request
3 local Response = bsnsPack.Response

8、如果想模塊化管理,把一個(gè)模塊所有的類通過一個(gè)文件暴露給其他模塊,可以在這個(gè)文件定義一個(gè)局部變量,把這個(gè)模塊所有的文件的類,都通過require導(dǎo)入進(jìn)來,并賦值給跟類同名的key,最后返回這個(gè)局部變量

文件bsns.lua

 1 local bsns = {}
 2 
 3 local bsnsPack = require("Assets.Lua.bsns.bsns_pack")
 4 bsns.Request = bsnsPack.Request
 5 bsns.Response = bsnsPack.Response
 6 
 7 bsns.BsnsMod = require("Assets.Lua.bsns.bsns_mod")
 8 bsns.BsnsCenter = require("Assets.Lua.bsns.bsns_center")
 9 
10 return bsns

9、可以實(shí)現(xiàn)一個(gè)通用的類定義函數(shù)

 1 --- define a class
 2 --- t._className, a string array, define class name
 3 --- t._super, a table, define super class
 4 --- t.__ctor, a function(self, ...), define member fields
 5 --- @param t any
 6 function class(t)
 7     -- extends super
 8     if t._super ~= nil then
 9         -- static fields and methods
10         local superStaticClone = {}
11         for k, v in pairs(t._super) do
12             if k == "_ctor" then
13                 goto continue
14             end
15 
16             superStaticClone[k] = v
17 
18             ::continue::
19         end
20 
21         setmetatable(t, superStaticClone)
22     end
23     
24     t.__index = t
25     -- new method
26     t.new = function(...)
27         local o = {}
28         invokeCtor(o, t, ...)
29 
30         setmetatable(o, t) -- bind class
31         return o
32     end
33 
34     function invokeCtor(o, cls, ...)
35         if cls._super ~= nil then
36             invokeCtor(o, cls._super, ...)
37         end
38 
39         if cls._ctor ~= nil then
40             setmetatable(o, cls)
41             o:_ctor(...)
42             setmetatable(o, nil)
43         end
44     end
45 
46     return t
47 end

有了這個(gè)函數(shù)可以這樣定義類

 1 local TestClass = class({
 2     -- class name
 3     _className = "TestClass",
 4 
 5     -- static fields:
 6     size = 2,
 7     count = 0,
 8 
 9     -- member:
10     _ctor = function(self, ...)
11         local params = {...}
12         self.count = params[1]
13         self.age = params[2]
14     end
15 })
16 
17 local TestClass2 = class({
18     _className = "TestClass2",
19     ---@class TestClass
20     _super = TestClass,
21 
22     _ctor = function(self, ...)
23         self.fdsl = 3256
24     end
25 })

10、簡單語法介紹

1)Lua里的語句不需要分號(hào);結(jié)尾

2)Lua常用的基本數(shù)據(jù)類型有nil、boolean、number、string、function、table

3)獲取數(shù)組長度用 #數(shù)組變量,例如

1 local array = {"Lua", "Tutorial"}
2 local len = #array
3 print(len)

4)遍歷數(shù)組用

1 for i, v in ipairs(table) do
2 
3 end

5)遍歷對(duì)象用

1 for k, v in pairs(obj) do
2 
3 end

6)其他語法請(qǐng)查閱菜鳥教程

11、Lua代碼規(guī)范可參考
https://lua.ren/topic/172/

熱門課程推薦

熱門資訊

請(qǐng)綁定手機(jī)號(hào)

x

同學(xué)您好!

您已成功報(bào)名0元試學(xué)活動(dòng),老師會(huì)在第一時(shí)間與您取得聯(lián)系,請(qǐng)保持電話暢通!
確定