有没有办法在 Godot 中创建真正的自定义类型?

Is there way to create TRUE custom type in Godot?

我正在尝试为我的播放器控制器创建自定义类型。

首先我使用了“脚本类”:

extends Node

class_name PlayerController

export var max_speed = 32
export var id = 1
export(NodePath) var node_path
onready var node = get_node(node_path)

...

但后来我意识到,并且对属性的显示方式不太满意:

我希望它像节点一样位于“PlayerController”专用部分,因此可以继承并在那里看到漂亮的属性堆栈。

我认为这是因为“脚本 类”与常规扩展相比是一种简化。所以我创建了一个。

tool
extends EditorPlugin

func _enter_tree():
    add_custom_type("PlayerController", "Node", preload("PlayerController.gd"),preload("PlayerController.svg"))

func _exit_tree():
    pass

结果完全一样。

我发现以这种方式创建的“自定义类型”不是“自定义类型”,而是附加了脚本的父类型。可以在文档中确认:

void add_custom_type(type: String, base: String, script: Script, icon: Texture)

Adds a custom type, which will appear in the list of nodes or resources. An icon can be optionally passed.

When given node or resource is selected, the base type will be instanced (ie, "Spatial", "Control", "Resource"), then the script will be loaded and set to this object.

You can use the virtual method handles() to check if your custom object is being edited by checking the script or using the is keyword.

During run-time, this will be a simple object with a script so this function does not need to be called then.

我的问题是: 是否可以创建真正的自定义类型?

在检查面板中添加类别

首先,如果您想要检查面板中的专用部分,您可以使用 tool(参见 Running code in the editor) script and _get_property_list

这是一个基于another answer的示例:

tool
extends Node

export var something_else:String

var custom_position:Vector2
var custom_rotation_degrees:float
var custom_scale:Vector2

func _get_property_list():
    return [
        {
            name = "Custom",
            type = TYPE_NIL,
            hint_string = "custom_",
            usage = PROPERTY_USAGE_CATEGORY
        },
        {
            name = "custom_position",
            type = TYPE_VECTOR2
        },
        {
            name = "custom_rotation_degrees",
            type = TYPE_REAL
        },
        {
            name = "custom_scale",
            type = TYPE_VECTOR2
        }
    ]

我正在创建一个名为“自定义”的类别。请注意 typeTYPE_NILusagePROPERTY_USAGE_CATEGORY。文档就是这样做的。参见 Adding script categories

使用 PROPERTY_USAGE_CATEGORY 将产生一个名为 header 的名称,类似于问题图片上的“节点”。使用 PROPERTY_USAGE_GROUP 创建一个可折叠组。

hint_string 的值将用作前缀。任何具有该前缀的 属性 都属于该类别。比如你在代码中看到的那些,每个都有各自的类型。这些都是在我的代码中用 var 声明的。但是,export 不行,因为那样它们会出现两次。


它看起来如下:


添加自定义类型

当我们在脚本中创建一个class时,它是一个类型。一个 GDScript 类型。用于证明它们是 GDScript 类型的证据。请注意,当使用 class_name 时,您可以声明该类型的变量,检查值是否属于带有 is 运算符的类型。并且您可以对它们使用 extends

还有核心类型。这也是 GDScript 类型。因此,您还可以使用类型的声明变量,对它们使用 extend 并使用 is.

检查它们

但是,我们在脚本中创建的 classes 不是核心类型。我们无法真正从 GDScript 或任何其他脚本语言创建核心类型。我们所能做的就是将脚本添加到现有的核心类型。

如果要创建实际的核心类型,则需要使用 C++ 并创建一个 Godot Module

您可能还对即将发布的 Godot 4.0 中的 GDExtension 感兴趣。