Scenes management

Godot Version

4.6.2

Question

I have various attack types and one of them is field_attack — spawning a field upon firing. Where is the best place to keep the field scene itself? (Clearly not as a constant like it is now.)

class_name AttackTypeHandler extends Node


func apply_attack(
	attack_types : Array[AttackType], 
	damage : float, 
	camera : Camera3D, 
	target : Node3D, 
	hit_point : Vector3, 
	normal : Vector3,
	enemy_group : String = "enemies"
) -> void:

func _apply_direct_attack(damage : float, target : Node3D, hit_point : Vector3, normal : Vector3) -> void:


func _apply_splash_attack(
	damage : float, 
	camera : Camera3D, 
	splash_radius : float, 
	hit_point : Vector3, 
	normal : Vector3,
	enemy_group : String
) -> void:


const FIELD_SCENE: PackedScene = preload("res://scenes/entity/field/Field.tscn")


func _apply_field_attack(
	damage : float,
	camera : Camera3D,
	field_radius : float,
	field_duration : float,
	hit_point : Vector3,
	normal : Vector3,
	enemy_group : String
) -> void:


func _apply_damage_to_target(damage : float, target : Node3D) -> void:

What’s wrong with keeping it in the constant?

If you want to change a lot for different enemies, make it an @export variable.

So It’s not a bad practice? That scene is just for technical reasons, wouldn’t change somehow

If you always are going to use it, or at least plan to use it more than 50% of the time, then no it’s not a bad practice. Otherwise you can turn it into a load statement and load it in the function when you need it. (But that could lag the game.)

1 Like

One small thing. Move the const to the top of your file.

also, in reading your code, you are passing a LOT of arguments. If they’re all necessary, think about creating a Resource that can hold references to all those values and pass it instead. It’ll make your code a lot easier to read.

class_name AttackTypeHandler extends Node

const FIELD_SCENE: PackedScene = preload("res://scenes/entity/field/Field.tscn")


func apply_attack(
	attack_types : Array[AttackType], 
	damage : float, 
	camera : Camera3D, 
	target : Node3D, 
	hit_point : Vector3, 
	normal : Vector3,
	enemy_group : String = "enemies"
) -> void:


func _apply_direct_attack(damage : float, target : Node3D, hit_point : Vector3, normal : Vector3) -> void:


func _apply_splash_attack(
	damage : float, 
	camera : Camera3D, 
	splash_radius : float, 
	hit_point : Vector3, 
	normal : Vector3,
	enemy_group : String
) -> void:


func _apply_field_attack(
	damage : float,
	camera : Camera3D,
	field_radius : float,
	field_duration : float,
	hit_point : Vector3,
	normal : Vector3,
	enemy_group : String
) -> void:


func _apply_damage_to_target(damage : float, target : Node3D) -> void:
1 Like

Thx, I will try to use Resource, because all of those arguments are used in functions rn

1 Like
class_name AttackDetails extends Resource


@export var attack_types: Array[AttackType]
@export var damage: float
@export var camera: Camera3D
@export var target : Node3D
@export var hit_point : Vector3
@export var normal : Vector3
@export var enemy_group : String = "enemies"

Then:

class_name AttackTypeHandler extends Node

const FIELD_SCENE: PackedScene = preload("res://scenes/entity/field/Field.tscn")


func apply_attack(attack_details: AttackDetails) -> void:


func _apply_direct_attack(damage : float, target : Node3D, hit_point : Vector3, normal : Vector3) -> void:


func _apply_splash_attack(attack_details: AttackDetails) -> void:


func _apply_field_attack(attack_details: AttackDetails) -> void:


func _apply_damage_to_target(damage : float, target : Node3D) -> void:
1 Like