Dose it makes sense to create a level unlock component for my game?
Right now all my levels have one script wich unlocks 1 specific level on winning wich feels so off to me, so i had an idea of a component wich gets addet to all my levels. The way i want this to work is i just make an export var called “level_to_unlock” (wich is an int) and a match block, wich for example when i winn and level_to_unlock matches 2 unlocks level2 and if level_to_unlock matches 3 unlocks level3.
Is ther a better way? Do you think this is a god idea?
The exported variable is a good idea, but you do not need a match block. That would become difficult to maintain as you add more levels.
For a linear game, store the progression in an Autoload such as Progress.gd:
extends Node
var highest_unlocked_level: int = 1
func unlock_level(level_number: int) -> void:
highest_unlocked_level = maxi(highest_unlocked_level, level_number)
Then each level only needs:
@export var level_to_unlock: int
func win_level() -> void:
Progress.unlock_level(level_to_unlock)
This keeps the level responsible for saying what it unlocks, while the Autoload manages the overall progression. You can later save highest_unlocked_level to a file so it remains unlocked after restarting the game.
That is fine, the levels can still be stored as booleans. Instead of having separate variables such as unlocked1, unlocked2, and unlocked3, you could group them into an array:
var unlocked_levels: Array[bool] = [
true, # Level 1
false, # Level 2
false # Level 3
]
func unlock_level(level_number: int) -> void:
var index := level_number - 1
if index >= 0 and index < unlocked_levels.size():
unlocked_levels[index] = true
Then each level can still use:
@export var level_to_unlock: int
and call:
Progress.unlock_level(level_to_unlock)
It works the same as your current booleans, but you will not need to add another variable and another match case for every new level.