如何在不实例化的情况下检查节点是否具有属性?

发布于 2025-01-14 22:43:10 字数 112 浏览 2 评论 0原文

我正在尝试检查某个节点类型是否具有属性
实际上不需要

像这样创建它的实例:

print("z_index" in Position2D);

I'm trying to check if a certain node type has a property
without actually needing to make an instance of it

like this:

print("z_index" in Position2D);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

触ぅ动初心 2025-01-21 22:43:11

ClassDB 中的类

如果我们谈论的是内置类(不是您创建的自定义类,而是 Godot 的一部分),您可以使用 ClassDB 来获取属性:

var properties := ClassDB.class_get_property_list("Position2D")

来自 Godot 脚本的类

如果该类不在 ClassDB 中(自定义类就是这种情况),但您有脚本,则可以使用脚本获取属性列表:

var properties := preload("res://custom_class.gd").get_script_property_list()

如果您没有脚本,也许你可以找到 它。此代码使用隐藏的项目设置“_global_script_classes”来查找给定您要查找的name_of_class的类的脚本路径,并加载它:

if ProjectSettings.has_setting("_global_script_classes"):
    for x in ProjectSettings.get_setting("_global_script_classes"):
        if x.class == name_of_class:
            return load(x.path)

附录:对于 Godot 4,请使用 ProjectSettings.get_global_class_list() 代替:

for global_class in ProjectSettings.get_global_class_list():
    if global_class["class"] == name_of_class:
        return load(global_class["path"])

其他类

但是,上述方法并不适用于每种类型的脚本。在这些情况下,恐怕最好的方法就是实例化。您仍然可以从实例中获取属性并缓存它们(也许将它们放入字典中),这样您就不会在每次需要查询时都创建一个新实例:

var properties := (CustomClass.new()).get_property_list()

查询属性

无论您如何获取属性列表,您都可以以同样的方式查询它们。例如,此代码查找名为 "z_index" 的属性并获取其类型:

var found := false
var type := TYPE_NIL
for property in properties:
    if property.name == "z_index":
        found = true
        type = property.type
        break

prints(found, type)

该类型是 Variant.Type 常量。

Classes in ClassDB

If we are talking about a build-in class (not a custom class that you created, but one that is part of Godot), you can use ClassDB to get the property:

var properties := ClassDB.class_get_property_list("Position2D")

Classes from Godot Scripts

If the class is not in ClassDB (which is the case custom classes), but you have the script, you can use the script to get the property list:

var properties := preload("res://custom_class.gd").get_script_property_list()

If you don't have the script, perhaps you can find it. This code uses the hidden project setting "_global_script_classes" to find the path of the script for a class given the name_of_class you are looking for, and loads it:

if ProjectSettings.has_setting("_global_script_classes"):
    for x in ProjectSettings.get_setting("_global_script_classes"):
        if x.class == name_of_class:
            return load(x.path)

Addendum: For Godot 4 use ProjectSettings.get_global_class_list() instead:

for global_class in ProjectSettings.get_global_class_list():
    if global_class["class"] == name_of_class:
        return load(global_class["path"])

Other classes

However, the above approach will not work for every type of script. In those cases, I'm afraid the best way is to instance it. You can still get the properties from the instance and cache them (perhaps put them in a dictionary) so that you are not creating a new instance every time you need to query:

var properties := (CustomClass.new()).get_property_list()

Query the properties

Regardless of how you got the property list, you can query them the same way. For example this code looks for a property with name "z_index" and gets its type:

var found := false
var type := TYPE_NIL
for property in properties:
    if property.name == "z_index":
        found = true
        type = property.type
        break

prints(found, type)

The type is a Variant.Type constant.

一个人的旅程 2025-01-21 22:43:11

Theraot 的答案是正确的,因为它提供了一种在不创建节点/gdscript 实例的情况下检查属性的方法。

您还可以通过执行以下操作来检查节点/场景的现有实例的属性:

if "attribute_name" in thing:
  pass # do stuff here

实际示例;在两个 Area2D 碰撞触发信号期间,检查一个节点的属性 item_type 是否已设置:

func _on_area_2d_area_entered(area):
  if "item_type" in area:
    print(area["item_type"])

Theraot's answer is correct, since it provides a way to check attributes without creating an instance of a node/gdscript.

You can also check the properties of an existing instance of a node/scene by doing this:

if "attribute_name" in thing:
  pass # do stuff here

Practical example; During a signal triggered by two Area2Ds colliding, check if one node's attribute item_type is set:

func _on_area_2d_area_entered(area):
  if "item_type" in area:
    print(area["item_type"])
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文