GDscript 中的类

2024年8月29日 | 阅读 8 分钟

脚本文件的主体是一个未命名的类,它只能作为资源或文件从外部引用。类语法的设计紧凑,只能包含成员变量或函数。允许使用静态函数,但不允许使用静态成员(这是为了线程安全,因为脚本可以在不知道用户的情况下在单独的线程中初始化)。同样,每次创建实例时都会初始化成员变量(包括数组和字典)。

以下是一个类文件的示例;

继承

类可以从以下类继承

  • 全局类
  • 另一个类文件
  • 另一个类文件中的内部类。

不允许使用多重继承。

继承使用 extends 关键字

要检查给定的实例是否继承自给定的类,可以使用 is 关键字

要调用基类(即,在我们当前类中 –ed 扩展的类)中的函数,请在函数名称前添加 . (

这很有用,因为扩展类中的函数会替换其基类中具有相同名称的函数。因此,如果我们仍然想调用它们,我们可以像其他语言中的 super 关键字一样使用它。 (点)

类构造函数

在类实例化时调用的类构造函数名为 _init。继承类时,会自动调用父类的构造函数。因此通常不需要调用 .init()

与上面示例中 .some_func 的常规函数的类不同,如果继承类的构造函数接受参数,则像这样传递它们

通过示例可以更好地解释这一点。假设我们有这样的场景

这里需要记住一些事情

  1. 如果继承的类 (State.gd) 定义了一个接受参数的 _init 构造函数(本例中为 e),那么继承的类 (Idle.gd) 也必须定义 _init 并将适当的参数传递给来自 gd_init
  2. gd 可以具有与基类 State.gd 不同的参数数量
  3. 在上面的示例中,传递给 gd 构造函数的 e 与移动到 Idle.gd 中的 e 相同。
  4. 如果 gd_init 构造函数接受 0 个参数,它仍然需要将一些值传递给 State.gd 基类,即使它不执行任何操作。 这使我们认识到,我们也在基构造函数中传递字面量,而不仅仅是变量。

示例

内部类

一个类文件可以包含内部类。内部类使用 class 关键字定义。它们使用 ClassName.new() 函数实例化。

类作为资源

存储为文件的类被视为资源。必须从磁盘加载它们才能在其他类中访问它们。这是使用 load 或 preload 函数完成的。通过在类对象上调用 new 函数来完成加载的类资源的实例化;

导出

可以导出类成员。这意味着它们的值会与它们附加到的资源一起保存。 它们可以在属性编辑器中进行编辑。导出通过使用 export 关键字来完成

导出的变量必须初始化为常量表达式,或者具有 export 提示,该提示以参数的形式传递给 export 关键字

导出成员变量的一个重要好处是使它们在编辑器中可见且可编辑。通过使用 export 关键字来完成发布。

导出成员变量的主要好处之一是使它们在编辑器中可见且可编辑。 这样,美术师和游戏设计师可以修改以后会影响程序运行方式的值。 提供了一种特殊的导出语法。

必须注意的是,即使脚本不在编辑器中,导出的属性仍然可以编辑。

请参阅下面的 (tool)

导出位标志

在位标志中使用的整数可以在一个属性中存储多个 true/ false 值。 通过使用导出提示 [int, FLAGS],可以将它们发送到编辑器。

也可以限制任何数量的编号标志中的标志。 语法类似于枚举语法。

在该示例中,Fire 的值为 1,Water 的值为 2,Earth 的值为 4,而 wind 对应于值 8。 通常,应相应地定义常量。

使用位标志需要了解一些按位运算。 如果有疑问,则应改为导出布尔变量。

导出数组

导出数组有效,但有一个重要的警告:虽然常规数组是为每个类实例本地创建的,但导出的数组在所有实例之间共享。 这意味着在一个实例中进行编辑将导致它们在所有其他实例中发生更改。 导出的数组可以具有初始化器,但它们必须是常量表达式。


Setter/getter

了解类的成员变量由于任何原因而发生更改时都很有用。 可能还需要以某种方式封装其访问。

为此,GDScript 提供了一种使用 setget 关键字的 setter/getter 语法。 它直接在变量定义之后使用

每当 variable 的值被外部源修改时(即,不是来自类中的本地用法),将调用 setter 函数(上面的 setterfunc)。

这发生在值更改之前。 setter 必须决定如何处理新值。 反之亦然,当访问 variable 时,getter 函数 getterfunc 上面) 必须 返回 所需的值。

示例

可以省略 setter 或 getter 函数中的任何一个

Get/Setter 在工具脚本或插件中将变量导出到编辑器以验证输入时特别有用。

本地访问不会触发 setter 和 getter。 下面是对此的说明