Using resources to spawn random enemy

Godot Version

Godot 4.4

Question

I am trying to spawn enemies into a simple turn-based battle scene by instantiating an “enemy unit” scene. I want to spawn in my blank “enemy unit” node with a custom resource attached. This is currently what the custom resource looks like.

extends Resource
class_name Enemy_data


@export var enemy_tex: Texture2D
@export var monster_name : String 
@export_group("Stats")
@export var Base_Stats :Stats
@export_group("")

The enemy Base_Stats get their values from another resource called Stats.

class_name Stats extends Resource

# Contains all BASE STATS for enemies AND Playable Characters

@export var max_health :int
@export var strength :int

I can instantiate the node into my battle scene if I manually load in a resource into the Inspector.

extends Node2D
class_name Enemy_Unit_Instance

@export var field:Enemy_data

func _ready() -> void:
	var enemy_health = field.Base_Stats.max_health
	var enemy_strength = field.Base_Stats.strength
	var enemy_tex = field.enemy_tex
	$Enemy_Unit_Sprite.texture = enemy_tex

The part I am stuck on is making the enemy unit scene use a random custom resource from the “Enemy_data” class. I want to instantiate the enemy_unit node, assign a random resource to it and add it to my scene. I have tried using an array but couldn’t figure out how to connect it to the node.

I am not super experienced with the resource pipeline but I would like to use them for this project. Using resources seems like a much more streamlined workflow than creating new scene and script for every enemy seems messy. Am I going about this all wrong by using resources this way?

I’m assuming you already have some enemy data resources called enemy1.tres etc.

class_name Enemy_Unit_Instance
extends Node2D

var field:Enemy_data

const enemy_datas: Array[String] = [
	"res://enemy1.tres",
	"res://enemy2.tres",
]

func _init() -> void:
	field = load(enemy_datas.pick_random())

I highly recommend continuing to use resources. You are not getting them wrong.

In my experience though, you should add a node to the tree before you assign data to it. Using your classes it would look something like this:

var unit := Enemy_Unit_Instance.new()
add_child(unit)
unit.field = random_data()

Ah I figured an array would be the right answer! I originally tried using an array, but I created it in a separate script which meant it would need to be passed into the enemy_instance script, which ended up overcomplicating things. This is a much simpler solution.