游戏开发Godot

Godot笔记:诡异的exported array行为

2019-05-22  本文已影响0人  吃烧烤的老王

export的作用类似于Unity中的[serializedfield]属性,即可以把一些字段曝光在节点的属性面板上以供编辑器修改。这种机制可以改善工作流,并大大提高开发效率。有些Unity基础的话,这些似乎是不难理解的。然而阅读文档的时候偶然发现了下面这段描述,突然让事情匪夷所思起来:

诡异的Exported Array

导出数组

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

原文见:https://docs.godotengine.org/zh_CN/latest/getting_started/scripting/gdscript/gdscript_basics.html#exports

下面是一个可以再现上文内容的情景

实例1:创建一个ArrayNode.gd

extends Node
export var array_test = []
 
func _ready():
    array_test.append(name)
    print(array_test)

场景里创建两个 ArrayNode1 和 ArrayNode2,并且都挂上ArrayNode.gd脚本,运行该场景.

我们期待输出结果为:

[ArrayNode1]
[ArrayNode2]

但实际上输出的是:

[ArrayNode1]
[ArrayNode1,ArrayNode2]

这种情境下(即仅声明了export未在编辑器内修改数组字段),ArrayNode1和ArrayNode2实际上引用的是同一个数组对象

实例2:

做个试验,依然使用实例1中的脚本ArrayNode.gd脚本实例化3个节点ArrayNode1,ArrayNode2和,ArrayNode3,在编辑器中将ArrayNode2的数组修改为[a,b,c],ArrayNode1,ArrayNode3不做任何编辑再运行场景结果如下:

[ArrayNode1]
[a, b, c, ArrayNode2]
[ArrayNode1, ArrayNode3]

这说明如果在编辑器中修改了某个实例的export数组,该实例的array会生成一个新的数组对象,而未在编辑器编辑过的实例则依然引用着同一个数组对象

总结:

这种设计确实有些诡异,这意味着数组类型的字段被export后有着和其它类型字段不同的行为,不清楚后面的版本会不会去掉这种“共享的”情况。好在我们一般使用export都是要在编辑内修改的,这就在一定程度上避免了共享的情况

上一篇下一篇

猜你喜欢

热点阅读