打包
- 把meshRenderer注释掉
- 把Lua文件要打进Per那个路径
- EmmyLua插件代码提示,需要打开资源目录哦,然后pull unity api在工作区右键栏目中,还有安装另一个插件,和另一个脚本。
脚本
- Lua全局变量优先从外面找,所以只要没有加local就是全局变量,切莫函数一个全局对象,外面一个相同的全局对象,而且还有两个要注意的地方,一个是需要require到该模块,还有如果在函数里的全局变量,需要执行才有哦。
- 元表不能执行元操作,t,k,v,表示设置的时候相关,k如果查找不到就为nil,不会要你设置的key
- Lua类对象中数据仅仅作为初始数据使用,之后实例化后,就和类对象没有关系了,各自开辟内存空间,所以类对象数据相当于静态数据
- 所以如果有:的方法就为实例方法,实例方法可以调用静态方法的操作,但是涉及到自己实例需要保存待数据必须用self去搞,谁调用冒号方法,就是把谁作为self带进去调用呢
- 类对象中new,请问应该是实例方法,还是静态方法。应该是实例方法,因为有可能有孙子去继承这个方法,而且只需要一个方法就可以形成所有后代的继承链
- 可以认为
new(obj)
,传表其实就是让其拥有一些自己的数据,考虑到实例化后要分配空间,其实也相当于拿来做初始化待,只不过不是覆盖关系,一个静态数据的age,一个实例化数据的age - require可以随便使用哦,很方便
- 在3级以上的继承关系,我们应该清楚的认识到,实例化的儿子,可以做孙子的类对象,也可以做它父亲的子实例化对象
- 面向对象总结,封装可以重新返回一个table解决,我们知道一个table和其方法都不加local。继承可以通过元表,然后设置元表的元方法实现,多态:默认是可以完全复写,不过要调用父类的方法怎么调用呢,如果直接super:xx(),你会发现你其实调用的父类的静态方法。根本不是和你作为儿子有另外内存数据的实例方法呢。
- 上面暂时我模拟不出来,还有多态也搞不定,暂时放弃多态!,暂时都先用复制代码解决问题,之后有机会看看巧克力Lua那个网易大佬的方案
- lua类函数中有一大错觉,以外能够直接获取age,其实获取不到,因为现在的age是全局变量,既不是lua类的静态age,也不是self传递对象的实例age
- 查错debug,pcall,error,assert
- Lua中有个很神奇的地方:不是说用了:就是实例方法比如如下:self先调用的实例化的GG方法,之后对于self来说MainManager:GG也相当于它这个类的静态方法,因为对于MainManager自己来说,他不过是MainManager.GG(go)的另一种形式罢了,关键看传递的是啥对象,既然是MainManager,那么它就是静态方法
function MainManager:InitGameState()
self:GG()
MainManager:GG()
end
--
function MainManager:GG()
print("gg")
end
--
- 在lua中,pairs是打印最全的,table的长度仅仅和字段有关,与“属性”无关,而且也和元表无关,如果原表的__newindex为一个table,其实就是给这个table赋值,如果为一个函数需要RawSet才行,当然了如果没有,默认就是可以赋值的。
- 在Lua中无论是ipair,还是pair,无论在哪里插入的字段,其中的key都是从1开始的,所以,insert默认是从#c开始的
- lua中变量坑,下面两种是不一样的key
print(j.str); print(j[str]);
- 有些类没有被Lua给注册,需要自己注册,然后点一下生产全部即可,如果发布1.0上线之后想热更的类这上面没有还是挺麻烦的
Lua中有个坑:
由于是从上到下检测的,倘若调用的函数是一个local的,不会获取的,除非在调用前定义!!,当然了都是全局函数,无所谓在哪里- 函数内定义的函数是全局的,如果加local估计就不是了
- do end包裹return
- Lua面向对象设计个人推荐最佳实践,严格区分类和实例,严格区分类相关和实例相关,类相关叫静态数据,无论字段,方法,都应该用.,只有实例的方法和属性才能用self,并且方法是需要:的
- 关于Lua的隐藏,我这里没有实现封装方法,也不打算弄,我的意见就是,不要在外面直接修改字段,要用某个类,必须先实例化,不可把实例化的对象放在模块里面。使用此类的对象持有之,调用方法也是用实例化的,不能直接调用类的,而且同样不能直接修改属性,必须通过方法才可以!!!!!
- 如果一个类本身是静态或者单例该如何处理呢?如果是静态类方法就不需要冒号了,而且不用写继承的New方法呢,直接使用就可以了,如果有静态类字段,还是通过方法获取不要直接修改。如果是单例模式的话,单例的方法哪怕有继承,也是静态的哦,如图所示的写法:
function Algo.GetInstance()
if Algo.ins == nil then
Algo.ins = Algo:New()
end
return Algo.ins
end
- 由于写get,set实在麻烦,暂时放弃给lua设置两个table来保持隐秘性,而且get,set已经有一部分隐藏了。。至少隐藏了字段
- 冒号方法的名字,不就是类.方法吗?嗯是呢、
- 在遍历的时候,k仅仅是字符串,不可直接拿来跟全局变量相比哦
- loadstring,热加载代码,这是一个函数,必须要调用才起作用呢
- string.gmatch()返回一个迭代器函数
- 方法中无论引用什么变量,都用local更安全
- LUA 中只有”nil“和”false“是false
- error方法第二个参数是错误环境的等级
- rawset绕过元方法
- setfenv设置环境,作用创建命名空间,或用第三方方便,推荐用继承一旦改变了环境,变量哪怕是全局都变成局部的了,当然可以通过父亲_G回到最初的地方
- 具名参数是通过table来完成的
- Lua可以省略(),比如调用方法xx{},请注意这种写法在闭包函数中会有错误哦
- 闭包
function Bibao()
local i =0;
return function()
i=i+1;
print(i);
end;
end;
local f =Bibao();
f();
f();
f();
f();
f();
f();
local f2 =Bibao();
f2();
f2();
f2();
- 不会引起混论,…表示多参数之外,还表示此文件的名字呢
module(...,package.seeall);
- select表示两种意思,a是可变参数的个数,b是第几个可变参数是啥
local a = select("#", ...)
local b = select(2, ...)
- 尽量别有和Mono相关联的lua类,因为这样一操作,编辑器就无法跳转了,这也太伤了吧
- :和 .的方法,之间不掉用self.xx没有严格限制,所以自己根据语境一定要严格区分好哦。
- Lua编程中规范,禁止类去调用实例方法?类可以调用静态方法,如果经手过Unity的,那么调用实例方法,必须要先找实例,如果静态方法就不需要了。。
- 判断一个类是不是静态的类的方式是,是不是只有一个New实例方法,如果还有实例方法就是非静态类,使用一定要继承
- TrieNode的New问题困扰我:已经解决了,是把chidren当作实例属性了,我擦!!,而且local变量可以省略self
TrieNode = {}
function TrieNode:New(obj)
local o = {isWord = false, children = {}}
setmetatable(o, self)
self.__index = self
return o
end
Trie = {
root = {}
}
function Trie:New(obj)
local o = {}
setmetatable(o, self)
self.__index = self
return o
end
function Trie:Insert(val)
local tempRoot = self.root
for i = 1, #val do
local char = string.sub(val, i, i)
if tempRoot.children[char] == nil then
tempRoot.children[char] = TrieNode:New()
end
tempRoot = tempRoot.children[char]
end
tempRoot.isWord = true
end
function Trie:Search(val)
local tempRoot = self.root
for i = 1, #val do
local char = string.sub(val, i, i)
if tempRoot.children[char] == nil then
return false
end
tempRoot = tempRoot.children[char]
end
return tempRoot.isWord
end
function Trie:StartsWith(val)
local tempRoot = self.root
for i = 1, #val do
local char = string.sub(val, i, i)
if tempRoot.children[char] == nil then
return false
end
tempRoot = tempRoot.children[char]
end
return true
end
local temp = Trie:New()
temp.root = TrieNode:New()
temp:Insert("apple")
print(temp:StartsWith("ap"));
print(temp:Search("appl"));
for key, value in pairs(temp.root.children) do
print(key, value)
end
- table可以做结构看看有啥问题呢
- Lua引用就是指向同一个呢
- 又有一个方法困扰我:后补这个方法也能看懂了,__call把一个表当作方法一样使用!!,setmetatable就是返回的第一表{10},设置了原表,再将其返回
function table_max_index(t)
local max_index = 0
for k, v in pairs(t) do
if max_index < k then
max_index = k
end
end
return max_index
end
mytable = setmetatable({10}, {
__call = function(mytable, newtable)
sum = 0
for i = 1, table_max_index(mytable) do
sum = sum + mytable[i]
end
for i = 1, table_max_index(newtable) do
sum = sum + newtable[i]
end
return sum
end
})
newtable = {10, 20, 30}
print(mytable(newtable))
- 把全局方法当作拓展方法!!
- Lua的字段会在元表链上找,这不注意容易引起bug
- Lua种一些不熟悉的地方,加快练习脚步
--repeat pcall,concat,entry用法,string.format
--tostring复写,嵌套函数,闭包,实现多继承,pack
- ToLua中__Tostring是无效的
- 在loadstring中,里面内容相当于一个匿名函数的body,获取到这个方法后,咱们还是要调用的哦
- unpack函数和table没有关系,拿来解包的东西
local g ={1,2,3};
local g2= unpack(g,2);
print(g2);
-
local parents = {...} 这个方法相当于插入,所以可以获取的table的长度呢
-
多继承的启示,匿名函数可以常驻内存中,只要设置了元表,才可以使用元方法。元表设置,不一定就是实例和类传递,也可能是类和一个匿名的元表进行了传递。而且其实主要是看__index是啥,如果是一个函数,就没必要想类和这个匿名元表为啥不设置地图关系
function Search(k, plist)
for i = 1, #plist do
local v = plist[i][k]
if v then
return v
end
end
end
function CreateClass(...)
local t = {}
local plist = {...}
setmetatable(
t,
{
__index = function(t, k)
return Search(k, plist)
end
}
)
t.__index =t;
function t:New()
local o ={}
setmetatable(o,t);
return o;
end
return t;
end
A = {}
function A:HH()
print("hh")
end
B = {}
function B:KK()
print("kk")
end
n1 = CreateClass(A, B)
local n1Instane =n1:New();
n1Instane:HH();
n1Instane:KK();
- 不管函数在哪里定义的都没有问题,返回了这个类,就能用这个类的方法呢
- 如果是table这种引用类型的,类在实例化的时候是不分配空间的,所以这点需要注意一下下,最佳实践,还是属性写在内里,特别注意的引用类型写在需要的地方,并注意之前的属性能够带下去不
- xlua chunkName不好,断点不能命中
- lua中存nil,自动忽略
- lua把公共函数写在主模块上,就不用操作_G了
- 如下图执行顺序,详解,先执行i=4,再执行和5比较是否是小于等于的情况,如果不是跳出,如果是执行方法体,然后执行-1的操作,之后循环起来的时候会忽略第一步i=4。
for i = 4,5,-1 do
print("woaini");
end