How to edit variables inside Inner Classes in the Inspector

Godot Version

Godot v4.3

Question

I am trying to learn OOP in GDScript and came across this problem:

If I create the variables (price and currency) in an inner class (Cost) within my class (Cookie) for the sake of organization, they do not pop up in the Inspector despite getting no error message from using @export, meaning I cannot edit the variables for each specific node. What am I to do?

While your class Cost exports variables, and you have an instance of the class Cost, you don’t @export that instance itself.

Then what do I @export? Do you have a solution to the problem?

@export var cost: Cost


error message :confused:

Then I don’t think it’s possible with a class defined within the script, you will have to use another script extending type Resource.

Or use @export_group to bundle the two cost related values.

Depending on your ‘top level’ class name of ‘Cookie’, your Cost logic should be done differently, I don’t think it should be a class. ‘Cost’ being an “object” based on a class doesnt seem right, ‘Cost’ a simple math calculation.

BUT IF YOU REALLY WANT A CLASS FOR ‘Cost’, then I recommend putting it in a different script file. Then, you can declare a variable as a cost type: ‘var cost: Cost’

EDIT:
Multiple classes within a class file IS POSSIBLE - they are called ‘inner classes’. I dont think I would ever use them, maybe if I had multiple slightly different classes that inherit from the same parent class I can just throw them in one file.

GDScript Reference - Inner classes

Everything in there is just an example, just so I can learn how to use it in the future, so you don’t have to think about the practicality of “Cost” itself.

I’m aware about inner classes, if you read the title again, my post is exploring how they work. The point is how can I have editable variables while using Inner classes?

Now while typing this reply out, I actually figured out what seems to be a viable solution ToT. I’ll attach it in another reply for y’all to review

This is the solution I found to the problem. I create an instance of Cost and @export the variables contained in that instance. I’m then able to edit those in the Inspector.

Let me know if you see anything wrong with this solution, or if there is a better one.

I still am curious why the variables did not show up in the inspector in the first screenshot, and what exactly @export did to those variables, since it ran that code without an Error message. It could be something worth looking into (preferably by someone more skilled than me).

price and currency as floats are copied so using the @exports cost.price will result in a different number from price

Not sure your solution works. Did you verify?

At the end you may have to do the simple way by assigning an export variable to the object’s property.


@export var my_cost:int
var obj_cost=Cost.new()

class Cost:
	var cost: int
	
# Check if the key is being pressed in the _process function
func _process(delta):
	if Input.is_action_pressed("ui_up"):
		obj_cost.cost=my_cost
		print(obj_cost.cost)

If you really, really, for some reason, really want to do that then you’ll need to use getters and setters for those variables

For example:

extends Node

var cost:Cost = Cost.new()
@export var price:float:
	get():
		return cost.price
	set(value):
		cost.price = value

@export var currency:String:
	get():
		return cost.currency
	set(value):
		cost.currency = value


func _ready() -> void:
	prints(cost.price, cost.currency)


class Cost:
	var price:float = 0.0
	var currency:String = ""
1 Like