实体脚本
每个具有 VScript (脚本) 功能的游戏都支持将脚本附加到服务器端实体。这些实体脚本可用于向实体添加新功能或逻辑,并且是一种以事件驱动方式编写脚本的便捷方式。
Contents
编写脚本
起源引擎
Hammer
在 Hammer 中,通过将脚本文件名或文件路径(当其位于 scripts/vscripts 文件夹内的另一个文件夹中时)添加到实体的Entity Scripts(不启用 SmartEdit 的情况下是vscripts
键值)键值 来分配实体脚本。该脚本在实体生成时执行,并加载到特定于每个实体实例的脚本范围中。脚本和所有变量和函数都可以通过实体访问,并在实体的生命周期内保持可用。
通过在 Entity Scripts 键值中指定多个脚本,可以将其他脚本加载到实体中,这与RunScriptFile
输入不同,因为它只是加载到根脚本范围[证实]。定义其他脚本时,请确保所有脚本名称都用空格分隔。
其他脚本
当您需要在游戏运行时制作实体脚本时使用的选项;CBaseEntity 提供的方法.ValidateScriptScope()
和.GetScriptScope()
用于现场编辑实体脚本。前者如果实体不存在则为其创建脚本范围,如果实体存在或成功创建则返回 true;后者返回一个包含脚本范围内所有内容的表,如果脚本范围存在,或者它不返回任何内容。
由于脚本环境由相互嵌套的关联数组或表组成,这就是为什么使用.GetScriptScope()
的时候返回一个表的原因。
这是一个正在创建并放入玩家的示例实体脚本:
脚本环境
起源1
脚本范围直接放在根表中,使用由唯一标识符后跟实体名称或类名称组成的键;_<uniqueID>_<entityname>
。所有实体只有在附加了脚本时才从脚本范围开始,因此在游戏运行期间,请始终确保使用 CBaseEntity.ValidateScriptScope()
方法创建脚本范围。该脚本始终定义了变量self
,指向拥有该脚本的实体的脚本句柄。
实体脚本有一个self
(起源1)或thisEntity
(起源2)对拥有它的实体的脚本句柄的引用,允许脚本轻松访问以控制实体通过它的类方法。
实体 I/O
参见 Vscript_Fundamentals#I.2FO_system_interaction
预定义的挂钩(Hooks)
实体可以从 C++ 端调用其脚本范围内的函数。常见的实体类具有预定义的函数调用,这些函数调用被编程到其中以在某些事件发生时发生,从而允许脚本执行代码。例如,在实体脚本中创建一个名为Precache()
的函数将在实体生成后立即调用该函数,从而允许脚本预缓存任何自定义资产。这些函数不需要注册,如果存在具有正确名称的函数,则始终调用它们。请参阅您的游戏的 API 文档以了解每个类可用的挂钩函数。
当从vscripts
键值加载多个脚本时,Precache()
和OnPostSpawn()
将被链接起来,以便在最终版本出现或两个脚本都被调用。
思考者(Thinker)函数
每个实体都支持一个思考者函数,默认情况下每 0.1 秒调用一次。think 函数只能由 Think Function 实体键值设置(不启用 SmartEdit 的情况下是thinkfunction
键值),或者用方法(Method)。然而在,AddThinkToEnt()
函数可用于将其自己的实体脚本函数分配为思考函数。
可以通过从函数返回一个浮点值来调整思考间隔,该值被解释为秒。您可以设置任何值,但会受到服务器刷新率(tick)的限制;30 的刷新率使得真正的最低值可能是 0.0333... 秒。
think 函数的示例脚本:
起源2
与起源1相比,起源2中实体脚本的脚本范围无法从根表访问。起源2中的实体同时具有公共和私有脚本作用域,并且预定义的实体脚本被加载到私有脚本作用域中。
该脚本始终定义了变量thisEntity
,指向拥有该脚本的实体的脚本句柄。
实体 I/O
CBaseEntity::ConnectOutput()
方法在起源2中似乎不起作用。要在实体输出上调用函数,可以将输出绑定到触发同一实体上的CallScriptFunction
输入。CallScriptFunction
输入将表中的激活者和调用者实体传递给被调用函数的第一个参数。
引用传递的句柄的示例 Lua 脚本。