Godot Version
4.3
Question
Hi,
I’m fairly new to all this, so there’s a great chance I’m doing things in a roundabout way–feel free to suggest improvements, it just may go over my head for a bit. With that out of the way:
I’m trying to set up a destructible object system where objects and enemies can either break apart (easy enough), freeze solid (still easy enough, in theory), or catch fire and spread fire to other burnable objects within a range. I’ve worked out an error-prone solution using one attachable scene as a burning mechanic, and one base scene as a burnable item. It’s pretty error-prone and I think attaching the new scene is causing weird issues that I’m not grasping yet, but the biggest issue is that it really flogs performance once 5 or so items catch fire–and I’d like to be able to have a patch of grass or a vine catch fire over time.
The other method I’ve been resisting is to have each object/enemy have a seperate burn-state object that would swap in, and trap all the mechanics in there, which would mean every WoodenBox also has a corresponding WoodenBox_burning object, etc. This seems a bit bloated to my mind, but open to it if it’s the best route.
What is the most effecient way to handle destructible/burnable objects, in way that doesn’t smash performance?
Here’s the burning mechanic:
extends Area2D
@onready var burn_check: Timer = $BurnCheck
@onready var burn_check_radius: CollisionShape2D = $BurnCheck_radius
@onready var burnable: Area2D = $"."
var burn_target = null
func _on_burn_check_timeout() -> void:
burn_check.set_wait_time(randf_range(0.4, 0.8))
check_burnable()
burn_check.start
print("timer restarting")
#burnable.monitoring = true
func check_burnable():
print("should be burn checking")
if burn_target != null:
if burn_target.has_method("take_burn_damage"):
burn_target.take_burn_damage()
print("checked and burning")
elif burn_target == null:
print("cant burn")
#burnable.monitoring = false
func _on_area_entered(area: Area2D) -> void:
burn_target = area.get_parent()
And here’s the burnable test object:
extends RigidBody2D
enum States {NOTBURNING, BURNING}
const BURNINGSCENE = preload("res://scenes/burning.tscn")
@onready var burntimer: Timer = $burntimer
@onready var burn_check: Timer = $Burning/BurnCheck2
@onready var burn_check_radius: CollisionShape2D = $Burning/BurnCheck_radius2
# This variable keeps track of the character's current state.
var state: States = States.NOTBURNING
var burn_health = 15
func _process(delta: float) -> void:
if burn_health <= 0:
state = States.BURNING
burntimer.start()
if state == States.BURNING:
modulate = Color(randf_range(0.1, 0.99), randf_range(0.1, 0.99), randf_range(0.1, 0.99))
var instancedscene = BURNINGSCENE.instantiate()
add_child(instancedscene)
func take_burn_damage():
if state == States.NOTBURNING:
burn_health -= 8
print(burn_health)
else:
return
func _on_burntimer_timeout() -> void:
queue_free()
Many thanks for any ideas.