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