引言
Lua脚本功能同样是ssRender引擎1.5版本新增的特性之一:通过编写部分Lua脚本,可以根据项目需求实现动态加载、动态渲染等效果,显著增加了开发者实现项目时的灵活度和效率。为开发者增加了更广阔的创作空间,灵活地实现复杂的界面效果,更好地实现自己的创意与构想。若大家想要了解更多关于ssRender引擎1.5版本新增的特性,可以参考如下两篇文章:
(ssRender引擎有关3D功能的归纳总结)(ssRender引擎有关3D粒子的归纳总结)
一:Lua脚本功能介绍
(一)Lua的调用方式
Lua脚本功能是触发式的调用,何为触发式?
简单举一个例子,在ssRender Editor工具有一个1.4版本就有的功能(详情可以参考SSRenderEdit使用理解与学习总结)Button按钮节点(1.5版本更新为Touch节点),可以在Touch节点的click事件中,去触发Lua脚本,如下图(Touch节点的Clicked事件,使用lua_call: 语法调用已经编写好的Lua脚本)
或者在某个节点的属性值变化时选择调用,如下图(Item0节点的Visible属性变化时,调用Lua脚本)
(二)为什么要使用Lua
该功能最重要的核心思想就是"动态"、"组合"、"联动"。
其实,在Lua脚本中编写代码实现的功能/效果等,都可以在工具端使用Binding绑定功能实现,或者结合PropertyChange功能实现。那么Lua脚本的意义是什么呢?
简单再举一个例子:当一个节点的Property或者某一个自定义的属性值改变后,有着大量节点需要跟着变动,比如说驾驶视角的切换(需要大量节点跟随着联动变化),在没有Lua脚本的时候,我们只能有唯一的方式去控制节点的变化:那就是使用大量的绑定。虽然绑定不会影响相关性能,但是不利于后期的维护以及增加新的功能(就像是增加了类之间的耦合度,牵一发而动全身!)
这时候,如果使用了Lua脚本来实现组合效果,就会简化开发,减少属性绑定之间的耦合程度!又由于Lua脚本是动态的,何时触发何时执行,所以不会影响界面预设的初始值!
在第二大版块,将会有一个结合以前展示过的有关3D节点的实际案例,来详细解说Lua脚本与Binding绑定之间对比的好处,拭目以待吧!
(三)Lua语法详解
本小结将会介绍与Lua功能实现的几个简单的语法,掌握这几个语法之后,熟悉使用ssRender引擎的Lua功能将会没有问题,如果想要学习更多关于Lua语言相关的知识,还请移步到Lua频道哦!
1:变量作用域
全局变量:Lua中的变量皆是全局变量,哪怕是语句块或是函数里,除非用 local 显式声明为局部变量,作用域为全局区。
局部变量:用local声明、作用域为从声明位置开始到所在语句块结束。
变量的默认值均为nil(可以类比NULL,但是不要相混淆,代表一个无效值)
请看如下代码:
function joke()
c = 5 -- 全局变量
local d = 6 -- 局部变量
end
joke()
print(c,d)
变量c被声明为全局变量,变量d被声明为局部变量
Print(c,d)的结果也可想而知,只能是c = 5,d = nil;
2:函数
在Lua中,函数是对语句和表达式进行抽象的主要方法。既可以用来处理一些特殊的工作,也可以用来计算一些值。在ssRender引擎中,函数则是各个小的Lua脚本的实现载体,调用Lua脚本,就是调用脚本内实现的函数。你可以在一个脚本内实现多个函数,在脚本同名的函数里内对其他函数进行调用。
Lua 提供了许多的内建函数,可以很方便的在程序中调用它们,如print()函数可以将传入的参数打印在控制台上。
Lua 函数主要有两种用途:
- 1.完成指定的任务,这种情况下函数作为调用语句使用;
- 2.计算并返回值,这种情况下函数作为赋值语句的表达式使用。
function max(num1, num2) --函数,比较两个数的最大值并返回
if (num1 > num2) then
result = num1; --将result声明为全局变量,保存最大值
else
result = num2;
end
return result;
end
Lua中我们同样可以将函数当做参数传递给其他函数
myPrint = function(param)
print("打印:",param)
end
function addFunction(num1,num2,functionPrint)
result = num1 + num2
-- 调用传递的函数参数
functionPrint(result)
end
-- myPrint 函数作为参数传递
addFunction(1,2,myprint)
--该函数的执行结果为:打印:3
多返回值/可变参数等特性大家若是感兴趣的话可以自行了解
3:数组
按照某一特定顺序排列组合的相同类型的数据元素,有一维数组和多维数组。
Lua的数组要区别于传统意义上的数组,它并没有专门的数组类型,它是用“table”这一数据结构实现的伪数组功能:索引可以由整数表示(一般由1开始,也可以设定为0开始),大小不固定
下面声明一个数组:
-- 创建一个数组
local array_1 = {1, 2, 3, 4, 5}
其中,array_1[1]的值为1,array_1[2]的值为2
可以用#来获取数组的长度
-- 计算数组长度
local length = #array_1
得到的length值为5
可以用for循环来遍历数组(几维数组就嵌套几个for循环即可遍历)
for i = 1, #array_1 do
print(array_1[i])
end
输出结果为1 2 3 4 5
4:表
table 是 Lua 的一种数据结构用来帮助我们创建不同的数据类型,如:数组、字典等。可以类比Java语言里的Map<key,value>,唯一索引对应着唯一的值。
Lua table 使用关联型数组,你可以用任意类型的值来作数组的索引(包括string),但这个值不能是 nil。
Lua table 是不固定大小的,可以根据自己需要进行扩容。
Lua中的table同样内置了许多方法,例如输出指定位置区间(注意是位置,而非索引)内所有元素、指定位置插入元素,输出所有key中对应的最大value值等等方法,感兴趣的话可以自行了解,这里只简单的对table的基础用法进行介绍:
-- 初始化表
mytable = {}
-- 指定值
mytable[1]= "Lua"
-- 移除引用,设为无效值
mytable = nil
-- lua 的垃圾回收会主动释放内存
(四)ssRender中Lua功能相关的接口
ssRender内置了很多与与项目内节点相关的配套函数接口,详情请参考ssRender引擎官方Lua帮助手册,下面介绍一些常用的接口:
1:总基类SSRObject对应的Lua接口
SSRObject是总基类,它所定义的接口它的派生类也可以使用,
其中我们常用的也就是一些set属性的接口,还有addChile()添加子节点的接口。
2:Item节点对应的Lua接口
Item类是SSRObject类的派生类,其他节点类要服用Item节点类的渲染特性,所以其他的节点类均由Item节点派生而得。所以一些公共属性对应的接口在其他派生类里可以直接使用。
常用的有一般属性的set接口,还有绑定/解绑缓动效果的bindBehavoir()接口和unbindBehavoir()接口
3:Text节点对应的Lua接口
Text类(由Item类派生而来,可以使用Item类的一般接口),它的特殊接口也一一对应着Text节点的特殊属性。
例如Text(文本内容)、Font(字体)、FontSize(字体大小)等等...
4:View节点与ViewItem节点对应的接口
如图:左下为View类,右下为ViewItem类,不再赘述,应用详情中的例子一将会详细介绍相关接口
5:其他节点
SeqImage节点类、Group节点类等其他节点类接口详情请见帮助手册,不在此赘述。
Scene 3D节点部分接口将会在第二个案例实现有详细介绍。
二:简单案例实现
本小节使用了ssRender工具的Lua脚本功能实现了两个简单的小例子,区别于之前的纯前端手灯拖拽创建,旨在帮助大家理解Lua脚本在ssRender引擎中的作用,大家可以发散思维,自己实现更多有趣、更加复杂的功能!
(一)Lua脚本实现歌曲菜单切换
此案例曾在(SSRenderEdit使用理解与学习总结)中的实际案例应用有过实现,在这里,我将会使用Lua脚本再次实现此功能:
1:创建Lua脚本
在Resource资源窗口下的Script脚本目录下,点击New LuaScript按钮新增Lua脚本文件
在弹出的窗口选择对应的Script Type脚本类型,填写脚本名称用于创建包含同名函数的脚本文件
双击新建的脚本文件,若安装了VSCode将会自动通过VSCode打开,未安装则可以同过文件所在目录下的resource\luaScript目录中打开对应lua脚本文件(初始化脚本文件如下)
ssRender引擎将会自动创建同名函数并且调用
2:编写Lua脚本
(1)获取将要添加的目标节点
这是一个特殊调用,ssr是内置对象,通过ssr.getNode("节点层级")函数获取节点目标
(2)创建Item、View、ViewItem新节点
如上图,创建新添加的Item、View、ViewItem节点的空对象
(3)节点初始化
Item节点
View节点
ViewItem节点(ViewItem节点仅设置的Source属性)(注意:Source属性中的Png文件要提前放置到工程文件的resource\images目录下)
(4)添加节点
调用总基类SSRObject声明的addChild方法,将各个节点添加至对应目录下
(5)添加触发事件
添加按钮,选中clicked事件,当按钮触发clicked事件后将会同时触发上述编写的脚本文件
(6)效果展示
现在,我们就添加了一个可以进行菜单切换的音乐列表啦!
进阶:接下来,我们使用Lua脚本添加一个Timer,控制列表轮播一便再回到第一个图片
(7)Lua添加Timer
将会使用如下接口:
①创建Timer
timerId =ssr.createTimer(1000, 1, TimerCbkCloseLayer, "0")
第一个参数是Timer的间隔时间
第二个参数是执行次数
第三个参数是启动Timer时调用的函数
第四个参数是传递给启动Timer时调用的函数的参数
此接口会有一个返回值,需要设置一个变量timerId来接收
实现详情和部分解析如下:
②启用Timer
根据步骤①的返回值,调用ssr.startTimer(timerId)接口启用Timer
如上图中的ssr.startTimer(timeId)语句
③Timer调用的函数
TimerCbkCloseLayer实现如下
(8)最终效果展示
如上图,将View节点添加到Page中之后,会实现每秒一次的轮播效果;
点击红色按钮会将上一层级的Item节点的Visible属性隐藏掉,大家可以试着自己实现一下。
(二)Lua脚本实现3D模型视角切换
在3D节点详解中(ssRender引擎有关3D功能的归纳总结),曾实现过一个摩托车模型的视角切换效果,当时应用了3-5个绑定进行实现的,效果如下图
这一个简单的小例子,在更改seeAngle属性时,为了同步更改显示效果就要使用较多的绑定数量。那么完全可以预见,复杂的项目工程中,为了更改效果可能会大量获取属性值,根据不同的属性值编写不同的逻辑,新增功能时要更改大量的绑定表达式!
所以,在这里可以再一次的了解Lua脚本功能在ssRender引擎中的作用,那就是:动态的组合联动,在新增功能时不用因为要修改以前编写过的功能而头疼,只需要新写一个Lua脚本,使用属性值来触发即可
(1)创建脚本
同实例一,不再赘述
(2)删除绑定
将与SeeAngle == 2 时绑定的属性值进行删除
(3)编写Lua脚本
在创建的Lua脚本内编写如下代码:
这里,我们就用到了第一版块的第三小节中的Table的用法:声明一个作用域为Local的setPropertyTable,将节点所在路径当做索引,目标设值当做Value,调用setNodeProperty()接口,以刚才声明的表当做参数,就能完美实现了!
效果如下:
小结:本篇文章是本人在使用ssRenderEdit工具中的Lua脚本相关内容时的学习理解,讲述了个人对Lua脚本在ssRender引擎中的作用,并且实现了两个简单的小例子,接下来本人会继续分享对ssRender引擎其他的学习理解,并且会继续深度探索ssRenderEdit工具其他实用功能!下一篇文章可能是使用Lua脚本在ssRender中开发一个简单的游戏实例,大家若是感兴趣,还请持续关注哦!