如何添加带提示和 hint_string 的数组?

How to add Array with hint and hint_string?

基于 的回答,可以像这样通过 _get_property_list() 创建导出变量:

var _properties := {
    "x": "",
    "y": ""
}

func _get_property_list() -> Array:
    if not Engine.editor_hint or not is_inside_tree():
        return []

    var result := []
    for property_name in _properties.keys():
        result.append(
            {
                name = property_name,
                type = typeof(_properties[property_name]),
                usage = PROPERTY_USAGE_DEFAULT
            }
        )

    return result
...

但是如果我想添加一个带有提示和 hint_string 的数组怎么办? 相当于 export(Array,float,0, 100,10) var Multiples=[0,0,0,0]

result.append(
{
  name = property_name,
  type = typeof(Array),
  usage = PROPERTY_USAGE_DEFAULT,
  hint=???,
  hint_string=???
}

如果您只需要规则,请滚动到显示“将所有内容放在一起”的末尾。


首先,我将使用如下所示的代码:

tool
extends Node

var backing_field

func _set(property:String, value) -> bool:
    if property == "property_name":
        backing_field = value
        return true

    return false

func _get(property:String):
    if property == "property_name":
        return backing_field

    return null

假设代码一直存在。所以我们将在 _get_property_list.

中指定此 属性 "property_name"

作为参考,我将首先展示 _get_property_list 在其他情况下的工作原理。例如,我们可以使 属性 成为 int:

func _get_property_list() -> Array:
    return [
        {
            name = "property_name",
            type = TYPE_INT,
            usage = PROPERTY_USAGE_DEFAULT,
        }
    ]

我们可以使用 hinthint_string 进一步指定它在检查器面板中的行为方式。例如,我们可以将 属性 缩小到一个特定的范围,如下所示:

func _get_property_list() -> Array:
    return [
        {
            name = "property_name",
            type = TYPE_INT,
            usage = PROPERTY_USAGE_DEFAULT,
            hint = PROPERTY_HINT_RANGE,
            hint_string = "0,10"
        }
    ]

这将使 属性 的范围从 010


我们当然可以指定 属性 是 Array 而不是 int:

func _get_property_list() -> Array:
    return [
        {
            name = "property_name",
            type = TYPE_ARRAY,
            usage = PROPERTY_USAGE_DEFAULT,
        }
    ]

这就是我们提出问题的地方:我们可以将 hinthint_stringTYPE_ARRAY 一起使用。

如果我们看一下 GDScript exports,我们会发现我们可以导出数组并指定元素的类型,如下所示:

export(Array, int) var my_array = [1, 2, 3]

因此,大概我们可以使用 _get_property_list 来做到这一点(如果不向 Pool*Array 类型提供资源——我们将无法用这些类型指定范围)。我们该怎么做? 我给你看


从这里开始,这些都是未记录的。 其中大部分是我通过实验得出的。顺便说一句,对于 Godot 4.0,这将有所不同。

指定数组元素的类型:

  • hint必须是24(这是我通过实验发现的一个无证常量,我在Godot源中找到了这个名字:PROPERTY_HINT_TYPE_STRING,但是它没有暴露给GDScript).
  • hint_string 必须是 TYPE_* 常量转换为 String 并在末尾附加 ":"

例如,如果元素的类型是 int,则将 "2:" 放在 hint_string 中。如果元素的类型是 float,则将 "3:" 放在 hint_string 上。像这样:

func _get_property_list() -> Array:
    return [
        {
            name = "property_name",
            type = TYPE_ARRAY,
            usage = PROPERTY_USAGE_DEFAULT,
            hint = 24,
            hint_string = str(TYPE_INT) + ":"
        }
    ]

供参考str(TYPE_INT)"2",所以str(TYPE_INT) + ":""2:"

好的,但是如果我们想指定更多关于元素的信息怎么办?例如,如果我们想说我们有一个 Array of int010 范围内使用 _get_property_list 怎么办?

在这种情况下,hint_string 将是:

  • TYPE_*常量转换为String
  • 其次是"/"
  • 后面的PROPERTY_HINT_*常量转换为String
  • 接着是":"
  • 后跟 hint_string,您将与 PROPERTY_HINT_* 常量一起使用。

像这样:

func _get_property_list() -> Array:
    return [
        {
            name = "property_name",
            type = TYPE_ARRAY,
            usage = PROPERTY_USAGE_DEFAULT,
            hint = 24,
            hint_string = str(TYPE_INT) + "/" + str(PROPERTY_HINT_RANGE) + ":0,10"
        }
    ]

此处 hint_string 显示为 "2/1:0,10"。请注意 "2" 现在后跟 "/" 而不是 ":"


好吧,这回避了问题。如果 Array 的元素也必须是 Array 怎么办?好吧,我们可以回到 Array 并指定类型,如下所示:

func _get_property_list() -> Array:
    return [
        {
            name = "property_name",
            type = TYPE_ARRAY,
            usage = PROPERTY_USAGE_DEFAULT,
            hint = 24,
            hint_string = str(TYPE_ARRAY) + ":"
        }
    ]

此处 hint_string 显示为 "19:"19" 来自 str(TYPE_ARRAY),我强调这一点是因为我将开始在代码中使用 "19" 而不是 str(TYPE_ARRAY)

好吧,假设我们要指定作为数组元素的数组元素的类型。例如,假设我们想要一个 int 数组的数组。那将是这样的:

func _get_property_list() -> Array:
    return [
        {
            name = "property_name",
            type = TYPE_ARRAY,
            usage = PROPERTY_USAGE_DEFAULT,
            hint = 24,
            hint_string = "19:" + str(TYPE_INT) + ":"
        }
    ]

此处 hint_string 显示为 "19:2:

我们可以放更多的 "19:" 来制作 ArrayArrayArray 的等等。所以这是 Array of Arrays of Arrays of ints:

func _get_property_list() -> Array:
    return [
        {
            name = "property_name",
            type = TYPE_ARRAY,
            usage = PROPERTY_USAGE_DEFAULT,
            hint = 24,
            hint_string = "19:19:" + str(TYPE_INT) + ":"
        }
    ]

此处 hint_string 显示为 "19:19:2:


现在,假设您想像以前一样 int01 的范围内,我们必须这样做:

func _get_property_list() -> Array:
    return [
        {
            name = "property_name",
            type = TYPE_ARRAY,
            usage = PROPERTY_USAGE_DEFAULT,
            hint = 24,
            hint_string = "19:19:" + str(TYPE_INT) + "/" + str(PROPERTY_HINT_RANGE) + ":0,10"
        }
    ]

此处 hint_string 显示为 "19:19:2/1:0,10

注意(再次)我们没有 "19:19:" + str(TYPE_INT) 后跟 ":" 而是 "/".


综合起来:

  • type必须是TYPE_ARRAY(即19)。
  • hint 必须是 24(这是一个未记录的常量)。
  • hint_string 必须是:
    • "19:" 用于我们想要的每一层嵌套 ArrayNone 如果 Array 不意味着在里面有其他 Array
    • 后跟表示元素类型的 TYPE_* 常量。
    • 然后:
      • 要指定元素的 hint_string 是什么:
        • "/"
        • 后面的PROPERTY_HINT_*常量转换为String
        • 接着是":"
        • 后跟 hint_string,您将与 PROPERTY_HINT_* 常量一起使用。
      • 否则:
        • ":"

其他属性不受此为数组的影响。你可以像你一样设置它们ere 制作数组元素类型的 属性。


这些是翻译成 hint_string 的 GDScript 导出的一些示例(请记住将 type 设置为 TYPE_ARRAY 并将 hint 设置为 24):

  • export(Array): ""
  • export(Array, int): "2:"
  • export(Array, Array, int): "19:2:"
  • export(Array, int, 0, 10): "2/1:0,10"
  • export(Array, Array, int, 0, 10): "19:2/1:0,10"
  • export(Array, int, "Red", "Green", "Blue"): "2/3:Red,Green,Blue"
  • export(Array, Array, int, "Red", "Green", "Blue"): "19:2/3:Red,Green,Blue"
  • export(Array, float): "3:"
  • export(Array, Array, float): "19:3:"
  • export(Array, float, 0, 100, 10): "3/1:0,100,10"
  • export(Array, Array, float, 0, 100, 10): "19:3/1:0,100,10"
  • export(Array, Texture): "17/17:Texture"
  • export(Array, Array, Texture): "19:17/17:Texture"

我做了什么样的实验才能发现这个问题?我导出了一些变量并查看了 get_property_list 报告的内容,然后在 _get_property_list 中尝试了不同的组合以查看哪些有效,哪些无效,哪些是必要的,哪些不是。然后我查看了 Godot 源代码作为完整性检查。

顺便说一句,最后记录的 hint 值为 22 的常量是 PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS。我们发现 hint 常量的值为 24,即 PROPERTY_HINT_TYPE_STRING23 发生了什么? 24 之外还有更多吗?有!参见 the source code。但这超出了这个答案。