0.概述
LUA系统是一套由事件触发到函数执行的代码体系,是在常规的Behavior、OCL路线之外,实现神秘游戏效果的利器,这篇文章将由浅入深地向大家介绍LUA系统的关键信息,帮助各位理解LUA系统的结构和用法。阅读本文需要用到SDK中LUA文件夹中的文件(主要是ScriptEvents.xml和Scripts.lua)
1.事件列表(EventList)
所谓的LUA系统到底说了一个什么事呢?其实用一句通俗的话概括就是“当_____的时候,就做_____的事情”,比如“当肚子饿的时候,就做吃饭的事情”,“当没弹药的时候,就做发动技能的事情”,“当重伤的时候,就做播放声效的事情”之类的。这个句子的条件状语,“当_____的时候”,在ScriptEvents.xml里的名字叫事件(Event),而这个句子后面的动词,“就做_____的事情”就是Scripts.lua里的函数(Function)。当然,SDK的源码本身也自带很多“当_____的时候,就做_____的事情”这样的句子,比如铁锤坦克有“当造好的时候,就做隐藏副炮模型的事情”这样的描述,都写在ScriptEvents.xml的事件列表(EventList)里。 这是我在测试LUA功能的时候写的一个EventList,它其实就是记录了这样的一句话:“当ReallyDamaged的时候,就做OnJapanAntiVehicleVehicleTech1ReallyDamaged的事情”。
2.LUA函数(LUAFunction)
“当Event的时候,就做Function的事情”,那到底做了什么事情呢?这时候我们就需要看看这个函数(Function)里到底有些什么东西了。用记事本或者UE啥的打开Scripts.lua,发现有一大堆function开头end结尾的东西,和我们通常接触的xml完全不同,这些就是LUA函数。到底做了什么事情呢?就是做了这些事情。这些“function”单词后面的一串就是这个函数的名字,我们在EventList里用到某个函数的时候,就要把函数的名字一字不漏地对应上。函数函数,谁是谁的函数?变量是什么?其实就是函数名字括弧里的东西,例如function kill(self) end,函数名字叫做kill,变量名字叫做self,这和我们中学学的函数是同一个道理,函数f(x),f就是函数名,x就是变量名。当然函数也可以有多个变量,它们之间会用“,”隔开。 我们费那么大力气去搞一个函数,当然想要它实现相应的功能,在这里,我们通常会调用系统自带的一套函数来实现想要的功能。例如,我想要做“海啸开纳米装甲”这个事情,就可以利用系统自带的ObjectDoSpecialPower函数来实现。我就写了这样的一个函数: function OnJapanAntiVehicleVehicleTech1ReallyDamaged(self) ObjectDoSpecialPower(self, "SpecialPower_ToggleEnergizedArmor" ) End 怎么理解这个东西呢?我们知道,函数是一种映射关系,在映射的彼岸,我们需要“海啸开纳米装甲”,那么在映射的此岸,我们就要给函数的变量赋予合适的值。这个函数ObjectDoSpecialPower,它只是描述一种映射,通俗地讲就是一种变化规则,是规则,而并不记录具体值,我们需要给它具体值才能让它动起来。ObjectDoSpecialPower函数有两个变量,第二个变量好说,用什么技能嘛,就是把技能名字写上去就行,不过注意要写在引号里,因为我们是直接写一个值,如果不写引号这就是一个变量名了。而第一变量表示谁用这个技能,这还用问?当然是海啸自己啦。但注意,我们不能直接写“海啸”或者“JapanAntiVehicleVehicleTech1”我们需要写的是【这个海啸】,这个海啸是哪个海啸?这在地图编辑器里很好说,“就是那个海啸!“我们可以这样说,然后在地图上指明一个海啸写进去;然而现在并没有一个具体的海啸,我们做mod的时候需要指涉一个抽象的海啸,怎么办?幸好,在主函数里,我们有一个self变量,这里面恰好就存储着【这个海啸】的信息,我们只需要把它用到ObjectDoSpecialPower函数里就可以了,于是,我们在第一个变量的位置写上self,和主函数的变量self一字不差,这就表示它们是同一个变量,从而给ObjectDoSpecialPower函数说明了抽象的【这个海啸】,到时函数运作起来的时候,该是哪个海啸开技能,哪个海啸就会被赋值到self变量中,进而成为ObjectDoSpecialPower函数的变量,正确地使用技能。需要注意的是,变量的名字和函数的名字一样是可以随意更改的,比如我如果讨厌self这个变量名,我写成 functionOnJapanAntiVehicleVehicleTech1ReallyDamaged(haixiao) ObjectDoSpecialPower(haixiao, "SpecialPower_ToggleEnergizedArmor" ) End 效果是一样的。 3.事件(Event) 我们知道LUA系统是“当Event的时候,就做Function的事情”。
做什么事情大概已经知道了,那“当Event的时候做”,到底是什么时候呢?这就要看ScriptEvents.xml中的三类事件(Event)了,分别是: 内部事件(InternalEvent),游戏系统自带的事件,简单好用,变量丰富 可编辑事件(ScriptedEvent),用户自定义的事件,要多少有多少,用的时候注册Name(类似AssetID,在这里叫Name)。 状态事件(ModelConditionEvent/ObjectStatusEvent) ,用户自定义的事件,用的时候也要注册Name,它们会根据ModelCondition或ObjectStatus的变化判断是否触发。 怎么理解事件(Event)的触发呢?用一句话来说就是“一旦_____,就有______事件”,第一个空是事件的触发条件,第二个空是事件名(Name)。
例如:一旦被打了,这个单位马上就有OnDamaged事件;一旦打光了弹夹,立刻有OnClipEmpty事件。不过要注意的是,事件描述的是行为,不是状态,是在说“弹夹打空了”而非“弹夹是空的”。一般的内部事件(InternalEvent)所描述的东西都可以从事件的名字里猜出来,比如OnDamaged、OnDestroyed、OnPowerOutage这些都很好理解。 而状态事件也好理解,比如
就是一个典型的状态事件,它表示一旦这个单位获得了REALLYDAMAGED的状态时,就视为有了ReallyDamaged这个事件。