godot icon indicating copy to clipboard operation
godot copied to clipboard

Exported arrays in extended scripts of inherited scenes all have the type of the first array declared

Open giulong opened this issue 1 year ago • 7 comments

Godot version

4.1.1.stable

System information

Godot v4.1.1.stable - Windows 10.0.19045 - Vulkan (Mobile) - dedicated NVIDIA GeForce GTX 965M (NVIDIA; 30.0.14.7219) - Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz (8 Threads)

Issue description

Let's have a Parent scene with a script attached. Its content doesn't matter, it can be empty. If we create an inherited scene from Parent, and extend its script exporting arrays like this:

extends Parent

@export var custom_resources:Array[CustomResource]
@export var plain_resources:Array[Resource]
@export var built_in_resources:Array[AudioStream]
@export var generic_array:Array

When saving the inherited scene, the editor will show this error: Cannot assign contents of "Array[Object]" to "Array[Object]". Reason: the types of the exported arrays are "overridden": they will all have the type of the first array declared.

The editor shows them correctly, all with their respective types:

InheritedEditor

But if you open the .tscn file with a text editor, you'll see this:

Inherited

When playing a scene composed of the inherited scene, the same error is shown in the debugger:

Debugger

Here's another example with the arrays exported in a different order. You can see that in the .tscn file they all have the type of the first one declared (which has no explicit type in this case).

InheritedSecondEditor InheritedSecond

N.B.: when dealing with just exported arrays of built-in resources (no exported arrays of custom ones), the behaviour in the .tscn file is the same, but no error is reported when running the scene.

Steps to reproduce

Import the attached example project and run it. You will se an error in the debugger view.

Otherwise, you can recreate it with these manual steps:

  1. Create scene A (can be just a Node2D) and attach a script to it (can be empty)
  2. Create scene B inheriting scene A
  3. Extend B's script and add a bunch of exported arrays, with different types
  4. Open B's .tscn file with a text editor and you'll see the exported arrays all have the type of the first array declared

Minimal reproduction project

CustomResourceTypedArrays.zip

giulong avatar Sep 10 '23 20:09 giulong

Note that this bug only occurs if the arrays are empty (or probably if they have the same content). If you fill them in (for both the base scene and the inherited one), the error will disappear.

Scene
[gd_scene load_steps=6 format=3 uid="uid://cmubfq7pnrbef"]

[ext_resource type="PackedScene" uid="uid://bulce0eugh1sb" path="res://scenes/Inherited.tscn" id="1_htqdq"]
[ext_resource type="Script" path="res://resources/CustomResource.gd" id="2_fvnv7"]

[sub_resource type="Resource" id="Resource_vsi5y"]
script = ExtResource("2_fvnv7")
x = 135

[sub_resource type="Image" id="Image_e2jvv"]

[sub_resource type="AudioStream" id="AudioStream_4xp28"]

[node name="Main" type="Node2D"]

[node name="Inherited" parent="." instance=ExtResource("1_htqdq")]
custom_resources = Array[ExtResource("2_fvnv7")]([SubResource("Resource_vsi5y")])
plain_resources = Array[Resource]([SubResource("Image_e2jvv")])
built_in_resources = Array[AudioStream]([SubResource("AudioStream_4xp28")])
generic_array = []
  • See #72514.

CC @vonagam

dalexeev avatar Sep 11 '23 10:09 dalexeev

Well if the error disappears with non-empty arrays then I agree that this is about constants collisions. Should be fixed relatively soon.

vonagam avatar Sep 11 '23 10:09 vonagam

Note that this bug only occurs if the arrays are empty (or probably if they have the same content). If you fill them in (for both the base scene and the inherited one), the error will disappear.

The arrays are declared (and exported) in the inherited scene only. If I initialise one like this:

extends Parent

@export var custom_resources:Array[CustomResource] = [CustomResource.new()]
@export var plain_resources:Array[Resource]
@export var built_in_resources:Array[AudioStream]
@export var generic_array:Array

in the .tscn file, the first array is nullified and the issue "cascades" on the remaining arrays, meaning they now all have the type of the first non-initialised array:

Scene

[gd_scene load_steps=3 format=3 uid="uid://bulce0eugh1sb"]

[ext_resource type="PackedScene" uid="uid://duty7mh70i7n5" path="res://scenes/Parent.tscn" id="1_pvs44"]
[ext_resource type="Script" path="res://scenes/Inherited.gd" id="2_ov75e"]

[node name="Inherited" instance=ExtResource("1_pvs44")]
script = ExtResource("2_ov75e")
custom_resources = null
plain_resources = Array[Resource]([])
built_in_resources = Array[Resource]([])
generic_array = Array[Resource]([])

Moreover, I cannot drag+drop resources from the editor: dragging any resources, custom or not, only works on the plain Array[Resource], not even on the non-typed Array.

If I manually add an element to the array, when i try to drop a resource of the same type, the field highlights correctly, but the resource is not added:

https://github.com/godotengine/godot/assets/27963644/031b562b-6536-4098-9336-3197c62117a0

giulong avatar Sep 11 '23 14:09 giulong

image image image I can reproduce the same error by doing this: pack a scene with editable children with the same export variable setup, and instantiate it. It might be the same issue.

rt9391 avatar Feb 11 '24 16:02 rt9391

~~Renamed to only "Arrays" as the same issue occurs with non-exported arrays.~~ Nope. I was wrong.

adamscott avatar Feb 23 '24 21:02 adamscott

Why the exported variables are shared ? and moreover, to save the proper type even why multiple changes and saves are required?

There is something wrong how the type is read from script and how the inspector handles it, because even if you give default values, it will still insert value as null, if you don't edit the variable in the inspector.

tokengamedev avatar Apr 01 '24 18:04 tokengamedev

I got this error when I was editing custom Resource. image

I was changing exported array's type from one custom Resource to another. I had a few custom resources saved on file and only 6 of them throw the error. It seems they did not updated after the change.

They ware keeping a reference to the old resource.

some_array= Array[ExtResource("1_8vs3l")]([])
image

I had to open each file in the Inspector and press save. Then the file of the custom resource got update to this:

some_array= Array[Resource("path_to_custom_resource.gd")]([])

and the errors stopped showing.

PS. The errors did not show which resource file was problematic, just the top parent gdscript/scene which was not very helpful for debugging.


v4.2.1.stable.official Windows 11 Pro 22631.3447

goranovs avatar Apr 24 '24 08:04 goranovs

Note that this bug only occurs if the arrays are empty (or probably if they have the same content). If you fill them in (for both the base scene and the inherited one), the error will disappear.

Scene

CC @vonagam

I am running into a similar problem where loading a PackedScene throws errors in the debugger when an export variable is an empty typed array. In my case, the warning is: image The scene being saved does not extend anything and the offending array is typed Array[NodePath] and is empty by default.

My project is large and so far I've not been able to reproduce the error in an MRP, but maybe this can be helpful to someone.

.

Godot v4.2.stable - Windows 10.0.22631 - GLES3 (Compatibility) - Intel(R) Iris(R) Plus Graphics (Intel Corporation; 27.20.100.9664) - Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz (8 Threads)

LO-0116 avatar Aug 14 '24 02:08 LO-0116