Duplicate function doesn't copy my GlobalEnums

The skillUpgradementType variable is always the 0

This is how i coded:

var newSkill = skillUpgradement.duplicate()

btw, skillUpgradement is a variable that references to an element in an Array

This is the SkillUpgradement class:

class_name SkillUpgradement extends Resource

var skillName : GlobalEnums.SkillName
var skillType : GlobalEnums.SkillType
var skillUpgradementType : GlobalEnums.SkillUpgradementType
var name:String = ""
var skillDescription:String = ""
var skillScene = null
var isUsed = false
var value = 0

func SetSkillName(SkillName):
	skillName = SkillName
	return self
func SetSkillType(SkillType):
	skillType = SkillType
	return self
func SetSkillUpgradementType(SkillUpgradementType):
	skillUpgradementType = SkillUpgradementType
	return self
func SetName(Name):
	name = Name
	return self
func SetDescription(Description):
	skillDescription = Description
	return self
func SetSkillScene(SkillScene):
	skillScene = SkillScene
	return self
func SetIsUsed(IsUsed):
	isUsed = IsUsed
	return self
func SetValue(Value):
	value = Value
	return self

oh, you’re duplicating the class object, not an instance of it, oops

Is there anyway for me to fix it?

have you tried skillUpgradement.duplicate(true)?

Yes, but the Global Enum variable still 0, it only duplicated the string variables

You could have an _init method so you can call skillUpgradement.new() to get an instance. There are other ways too.

then just reassign it

var newSkill = skillUpgradement.duplicate()
newSkill.SetSkillUpgradementType(the type you wanted)
1 Like

As per documentation of duplicate() function, it only copies variables marked with @export by default:

Duplicates this resource, returning a new resource with its exported or PROPERTY_USAGE_STORAGE properties copied from the original.

If you want to export others, you need to flag them by adding this func to your class:

func _get_property_list() -> Array:
	return [
			name = "skillName",
			type = TYPE_INT, # or whatever it is
			name = "skillType",
			type = TYPE_INT, # or whatever it is
			name = "skillUpgradementType",
			type = TYPE_INT, # or whatever it is
		# etc etc

PS: Why do you have “return self” at the end of every Set func? It doesn’t hurt per se, but it’s a smell of either an accident or bad code design. Your code, your choice, but I’d generally advise against doing this. So just:

func SetSkillName(SkillName):
	skillName = SkillName

Finally, it’s again your choice, but most people follow same convention in gdscript when it comes to variable and method names: always lower-case and using _ between words, so:

func set_skill_name(_skill_name):
	skill_name = _skill_name

It’s just easier for anyone else working in gdscript to understand it, then. Your call, just thought I’d point it out.


1 Like

the skillUpgradement holds the information that i want to duplicate, example i want 4 swords fly around me

There is a big difference between your class that you defined with class_name and an instance of that class, and until you don’t understand why they are different, you’re not gonna be making any games with godot.

Maybe I explained something wrong or maybe the way i did it is wrong, so I have an Array that holds all the skills, i want to pick a skill in that Array and give it to the Player, I can’t .new() the skillUpgradement because the variables are gonna be empty

Wow, It’s working, thank you very much sir but the String variables in my class aren’t exported too, why does it get duplicated?

new_skill = your_array[index].duplicate()
You want to duplicate the instance in the array, not the class object.
You can also do it like

for skill in your_array:
  if check_this_is_the_skill_I_want(skill):
    new_skill = skill.duplicate()
1 Like

Yeah i just thought about that when talking with you haha, but my problem could be the same, that guy above just fixed it, i’ll fix my code as you said too, thanks

Hey, can i ask something?, in my class, there’s a skillScene that contains a PackedScene, what’s the type of a PackedScene?

A PackedScene is an instance of the PackedScene class which extends Resource, so it is only loaded once and it can be instantiated into a scene node that can be added to a node tree. So the actual answer may depend on the context you are seeing this in, because of automatic casting/instantiation.

I just used the Packed Byte Array because i thought everything is just bunch of bytes and and it worked lol

Just ctrl+click (cmd+click on mac) on the class name to read the documentation… :face_with_peeking_eye:

Just like Material is a Resource that stores properties of a material, PackedScene is a Resource that stores properties of a given scene. When you do load(“res://scenes/test.tscn”), that returns a PackedScene, which is just a Resource file with variables that describe the scene. Once you then do instantiate() on it, only then a real scene object is created and returned. It does so by reading information from PackedScene resource file, such as what dependencies a scene has and where to find them.

If you do this:

@export var some_scene: PackedScene

then in the editor you will be able to drag-drop a scene into the “Some Scene” property in the Inspector on the right side. This is better than hard-coding path to the scene b/c if you then move the scene file to another folder, hard-coded path will no longer be valid, but if you assigned the scene to the @export variable in the editor, it will auto-update to new path.

Hope this helps!

1 Like

When I tested it locally, string variables were not being duplicated either.

If I remember incorrectly, though, and you’re right about this, then it’s possible that certain types have the PROPERTY_USAGE_STORAGE flag by default. Either way, if you do what I said above for all properties, you’re good to go.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.