实体脚本

From Valve Developer Community
Jump to: navigation, search
English (en)中文 (zh)
... Icon-Important.png

每个具有 VScript (脚本) 功能的游戏都支持将脚本附加到服务器端实体。这些实体脚本可用于向实体添加新功能或逻辑,并且是一种以事件驱动方式编写脚本的便捷方式。

编写脚本

起源引擎

Hammer

info_survivor_position 实体来自 Left 4 Dead 2,得到 2 个脚本定义为其实体脚本
Icon-Bug.pngBug:Open Source... 按钮没有任何作用,所以你可以忽略它。

在 Hammer 中,通过将脚本文件名或文件路径(当其位于 scripts/vscripts 文件夹内的另一个文件夹中时)添加到实体的Entity Scripts(不启用 SmartEdit 的情况下是vscripts键值)键值简体中文来分配实体脚本。该脚本在实体生成时执行,并加载到特定于每个实体实例的脚本范围中。脚本和所有变量和函数都可以通过实体访问,并在实体的生命周期内保持可用。

通过在 Entity Scripts 键值中指定多个脚本,可以将其他脚本加载到实体中,这与RunScriptFile输入不同,因为它只是加载到根脚本范围【证实】。定义其他脚本时,请确保所有脚本名称都用空格分隔。

Note.pngNote:所有定义的脚本都将加载到相同的脚本范围内,从而覆盖任何相同的非局部变量和函数!

其他脚本

当您需要在游戏运行时制作实体脚本时使用的选项;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)。然而在Left 4 Dead 2,AddThinkToEnt()函数可用于将其自己的实体脚本函数分配为思考函数。

可以通过从函数返回一个浮点值来调整思考间隔,该值被解释为秒。您可以设置任何值,但会受到服务器刷新率(tick)的限制;30 的刷新率使得真正的最低值可能是 0.0333... 秒。

Note.pngNote:Left 4 Dead 2 中,继承 CTerrorPlayer 类的实体的上限为 0.0666... 秒,是游戏默认刷新速度的一半。

think 函数的示例脚本:


起源2

与起源1相比,起源2中实体脚本的脚本范围无法从根表访问。起源2中的实体同时具有公共和私有脚本作用域,并且预定义的实体脚本被加载到私有脚本作用域中。

Blank image.pngTodo: 如何使用公共脚本范围?
证实:起源2是否实现了脚本挂钩?

该脚本始终定义了变量thisEntity,指向拥有该脚本的实体的脚本句柄。

实体 I/O

CBaseEntity::ConnectOutput()方法在起源2中似乎不起作用。要在实体输出上调用函数,可以将输出绑定到触发同一实体上的CallScriptFunction输入。CallScriptFunction输入将表中的激活者和调用者实体传递给被调用函数的第一个参数。

引用传递的句柄的示例 Lua 脚本。



思考者(Thinker)函数

参见 Dota_2_Workshop_Tools/Scripting/ThinkerFunctions