• Godot HelpProgramming
  • Can I declare variables in a parent class and then immediately set them in child classes?

I'm trying to make a weapon system for a game I'm working on, but I'm trying to store data about each weapon in a class. I'm encountering an error saying that the member already exists in a parent class, but nothing I've read has helped me solve that so far.

#weapon.gd
extends Node

class_name Weapon

var identifier = "Unknown Weapon"
var damage = 0
var damageModifier = 0
var tier = -1


#Weapons.gd [Singleton]
extends Node

class NiLGun extends Weapon:
	var identifier = "NiL Gun"
	var damage = 1000
	var damageModifier = 0
	var tier = 5

class BaseMachineGun extends Weapon:
	var identifier = "Machine Gun"
	var damage = 5
	var damageModifier = .1
	var tier = 0

There is also a chance that I don't understand how having multiple classes in one script works, but can anyone help me?

Another way of doing this is to use one code on multiple weapons, like this:

extends Node
export var identifier = "Unknown
export var damage = 0
export var damageModifier = 0
export var tier = -1

Then add that script to each weapon, and you can change the exported variables for each one.

Then, on another node, add a function like this to select each weapon if you have it.

func select_weapon(selected_weapon):
	hide_all_weapons() #All this is is a code I use to make all the weapons hide before being chosen. It's mostly get_node(whatever).visible = false for every weapon. 
	if selected_weapon == name:
		selected_weapon.show()

Selected weapon, in my case, was actually an integer which each weapon had. Then, for each child of the parent node that holds the weapons, if the chosen weapon has the same number as one of the weapons, use that child's stats- but you can also use a weapon's name.

That would require tons of scripts and it wouldn't have a base class that anything inherits (That's pretty much my "if nothing else works" strategy"

The point of these classes is to store data, so maybe I can use something like a JSON file. The issue then is that I need to know every key of the file at any point in time so that the editor can have a list to choose from when doing things like spawning weapons.

As far as your first script goes, you are trying to re-declare the same variable. It's already declared, so you have to set it in a function:

#base class
var identifier

func set_identifier(gun):
	identifier = gun

you would write a func for each one. Then set it in the ready function of the inherited class. I think you could also use set/get on the variable without a function so you might want to look that up in the docs. I think you could also just set the variable in the ready function of the inherited class:

func ready():
	indentifier ="whatever"

I generally set inherited variables in the init() function, since not all of my classes are nodes, and init() takes the parameters you pass to new().

You would use an _init() function for this:

Animal.gd

extends Node2D

class_name Animal

var saying

func say():
	print(saying)

Cat.gd

extends Animal

class_name Cat

func _init(word):
	saying = word

Main script

extends Node2D

func _ready():
	var cat = Cat.new("Meow!")
	cat.say()
	print(cat is Cat) # this is True

What I'm getting is that this is impossible and that I either have to define each variable seperately without having them on the parent class or set them in the _init function, which is passed arguments from example.new("a", 3)

It's exactly not impossible. It's that it's a syntax error and maybe you don't fully understand OOP. You are attempting to redefine a variable in the same class (or child class), which is an error in most languages. Basically you are making a new member variable with the same name, which doesn't make sense, when you wish to simply set the value to something different. You can also do this if you don't want to create the new instances in that file:

class NiLGun extends Weapon:
    func _ready():
        identifier = "NiL Gun"
        damage = 1000
        damageModifier = 0
        tier = 5

When you extend a class, just think of it as one class. You wouldn't declare a variable and then declare it again on the next line. You already did that.

@cybereality said: It's exactly not impossible. It's that it's a syntax error and maybe you don't fully understand OOP. You are attempting to redefine a variable in the same class (or child class), which is an error in most languages. Basically you are making a new member variable with the same name, which doesn't make sense, when you wish to simply set the value to something different. You can also do this if you don't want to create the new instances in that file:

class NiLGun extends Weapon:
    func _ready():
        identifier = "NiL Gun"
        damage = 1000
        damageModifier = 0
        tier = 5

I understand, but in my previous statement this is pretty much what I said: You have to set them later.

@Perodactyl said:

I understand, but in my previous statement this is pretty much what I said: You have to set them later. It would only be a slight change from your first post:

d me solve that so far.

#weapon.gd extends Node class_name Weapon var identifier = "Unknown Weapon" var damage = 0 var damageModifier = 0 var tier = -1 #Weapons.gd [Singleton] extends Node class NiLGun extends Weapon: func ready(): identifier = "NiL Gun" damage = 1000 damageModifier = 0 tier = 5 class BaseMachineGun extends Weapon: func ready(): identifier = "Machine Gun" damage = 5 damageModifier = .1 tier = 0


Indention got messed up.
However,  I think I would use a resource dictionary and fill it at creation  from a space point of view unless there weren't too many weapons.
6 months later