【问题标题】:Is there way to create TRUE custom type in Godot?有没有办法在 Godot 中创建真正的自定义类型?
【发布时间】:2022-04-14 02:15:15
【问题描述】:

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

首先我使用“脚本类”:

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)

添加自定义类型,该类型将出现在节点或资源列表中。可以选择传递一个图标。

选择给定节点或资源时,将实现基本类型(即“空间”,“控制”,“资源”),然后将加载脚本并将其设置为此对象。强>

您可以使用虚方法handles() 来检查您的自定义对象是否正在被编辑,方法是检查脚本或使用is 关键字。

在运行时,这将是一个带有脚本的简单对象,因此不需要调用此函数。

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

【问题讨论】:

    标签: godot


    【解决方案1】:

    在检查器面板中添加类别

    首先,如果您想要检查器面板中的专用部分,您可以使用tool(参见Running code in the editor)脚本和_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 将产生一个命名标题,类似于问题图片上的“节点”。使用PROPERTY_USAGE_GROUP 制作可折叠组。

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


    它看起来如下:


    添加自定义类型

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

    还有核心类型。这也是 GDScript 类型。所以你也可以使用声明类型的变量,对它们使用extend,并使用is检查它们。

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

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

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

    【讨论】:

    • 谢谢,我看到与 GDExtreinsion 一起引入的新类型系统是我所说的:“新的注册系统现在是 Godot 的 ClassDB 的一部分。这意味着在插件中实现的类与核心没有区别课。” GodotModules 似乎无法嵌入到项目中
    • @majkrzak 正确。好吧,当前的 GDNative 是一个中间立场。如果您使用 C++ 的动机是性能,那么我会说使用 GDNative。但是现在,Godot 模块是做一些事情的唯一方法,比如这个。顺便说一句,这种区别对我们不利:get_classis_class 仅适用于核心类。您可以将自己的get_classis_class 添加到您的脚本中,但它们只是隐藏了其他的,因为它们不是虚拟的。因此,如果您有一个类型为 Object 的变量,它会调用原始变量。哪种方式违背了目的。
    猜你喜欢
    • 2021-12-22
    • 2016-08-25
    • 2010-10-23
    • 2019-08-22
    • 2019-10-06
    • 1970-01-01
    • 2011-04-10
    • 1970-01-01
    • 2021-09-21
    相关资源
    最近更新 更多