Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom resources return null when running the scene, despite being shown as existing in the editor. #74475

Closed
Azagwen opened this issue Mar 6, 2023 · 8 comments
Labels

Comments

@Azagwen
Copy link

Azagwen commented Mar 6, 2023

Godot version

v4.0.stable.official [92bee43]

System information

Windows 10,

Issue description

I have two custom resources that exist as class scripts in my project, and I can select them just fine in the inspector and set parameters however I like. And their resource dropdown tells me that they're being saved properly in the scene with a proper path.

BUT When I run the scene, all resources that I have changed in the inspector are treated as <null>, while all the resources of which I didn't change the value in the editor retain their default code values. Am I doing something wrong, or is Godot being silly?

Here is the code for both of my custom resources:

extends Resource

class_name NumberRange

@export var min: float
@export var max: float

func _init(min, max):
	self.min = min
	self.max = max
extends Resource

class_name MovementGoalAngleLimits

@export var angles_x: NumberRange
@export var angles_y: NumberRange
	
func _init(angles_x: NumberRange, angles_y: NumberRange):
	self.angles_x = angles_x
	self.angles_y = angles_y

and here is the @export variable they're used by:

@export var fov_limits := MovementGoalAngleLimits.new(NumberRange.new(-20, 20), NumberRange.new(-30, 30))

the @export variable above is recognized just fine, but if I dare to change it, it just outputs null

Steps to reproduce

  • Create two scripts with the code provided above
  • Create an @export variable in another script attached to a random node with a default value, and add a call the resource with a null check and a print
  • Create a new instance of the resource in the inspector to override the default
  • run the scene

Minimal reproduction project

This project is the one that has the issue, it's only a scene with a few interaction points and a print already present where the issue occurs. Clicking on the goal in the blue area of the map should cause the print to start printing <null> repeatedly
example_project.zip

@darloth
Copy link

darloth commented Mar 6, 2023

I believe I'm having this issue as well. When you run your test project under the debugger, are you getting some
_create_instance: Error constructing a GDScriptInstance. errors?

@AThousandShips
Copy link
Member

AThousandShips commented Mar 6, 2023

The instances cannot be default constructed which causes bugs somewhere, not sure why, but at minimum the error needs to be more clear.

But as a workaround you need to make the types have default arguments:
MovementGoalAngleLimits:

func _init(angles_x: NumberRange = NumberRange.new(), angles_y: NumberRange = NumberRange.new()):

NumberRange:

func _init(min: float = 0, max: float = 0):

@AThousandShips
Copy link
Member

Duplicate of #67059

@Azagwen
Copy link
Author

Azagwen commented Mar 6, 2023

I believe I'm having this issue as well. When you run your test project under the debugger, are you getting some _create_instance: Error constructing a GDScriptInstance. errors?

I get no errors no, the resources just become null as soon as I run the scene.

@AThousandShips
Copy link
Member

I get errors when I run your project

@Azagwen
Copy link
Author

Azagwen commented Mar 6, 2023

The instances cannot be default constructed which causes bugs somewhere, not sure why, but at minimum the error needs to be more clear.

But as a workaround you need to make the types have default arguments: MovementGoalAngleLimits:

func _init(angles_x: NumberRange = NumberRange.new(), angles_y: NumberRange = NumberRange.new()):

NumberRange:

func _init(min: float = 0, max: float = 0):

This does fix it! Thank you for letting me know 💖
And yeah I feel it should either be explicitly stated that this needs to be done, or that Godot should find a way to fix it 🤔

@darloth
Copy link

darloth commented Mar 6, 2023

Duplicate of #67059

Following the chain from this did indeed help me resolve my issue which was of course the one mentioned, but I agree it should absolutely be made more clear to users that they shouldn't be writing _init with parameters for anything that will be instanced by/in a scene. I ended up deleting a lot of what was effectively unnecessary boilerplate (admittedly, it was useful back in 3.5 because back then you couldn't export custom resource types) and then it just worked once I'd got rid of enough of the stuff that was relying on doing stuff in initialization. Perplexing though as it wasn't obvious and I didn't find a note about it in documentation either.

@AThousandShips
Copy link
Member

That's what the proposal godotengine/godot-proposals#1513 is about

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants