Improves tree and ground tile appearance

Refactors tree spawning and rendering:
- Adds seasonal color variations for trees via scripts.
- Introduces `ColorStorage` to manage tree and grass colors
- Removes unused code from tree spawning logic.
- Adjusts ground tile color for better visual appeal.
- Hides debug text on ground tiles.
This commit is contained in:
Dan Baker 2025-06-28 17:21:50 +01:00
parent 734730beee
commit ea5006e8a2
28 changed files with 454 additions and 63 deletions

View file

@ -0,0 +1,108 @@
class_name TreeColorDefault
extends RefCounted
var tree_name: String = ""
var current_season: String = "summer"
var mesh_instances: Array[MeshInstance3D] = []
func set_tree_info(name: String, season: String):
tree_name = name
current_season = season
func set_leaf_color(model_instance: Node3D):
#Log.pr("Setting leaf color to: %s" % color)
pass
func set_trunk_color(model_instance: Node3D):
#Log.pr("Setting trunk color to: %s" % color)
pass
# Update a specific material by name with a new color
func update_material_by_name(root_node: Node, material_name: String, new_color: Color) -> bool:
var updated = false
for mesh_instance in mesh_instances:
if update_material_in_mesh_instance(mesh_instance, material_name, new_color):
updated = true
return updated
# Update multiple materials at once
func update_materials_by_names(root_node: Node, material_updates: Dictionary) -> Dictionary:
var results = {}
# Initialize results
for material_name in material_updates.keys():
results[material_name] = false
for mesh_instance in mesh_instances:
for material_name in material_updates.keys():
var new_color = material_updates[material_name]
if update_material_in_mesh_instance(mesh_instance, material_name, new_color):
results[material_name] = true
return results
# Get all material names from a model
func get_all_material_names(root_node: Node) -> Array[String]:
var material_names: Array[String] = []
for mesh_instance in mesh_instances:
var mesh = mesh_instance.mesh
if mesh:
for i in range(mesh.get_surface_count()):
var material = mesh.surface_get_material(i)
if material and material.resource_name:
if not material.resource_name in material_names:
material_names.append(material.resource_name)
return material_names
func update_material_by_name_with_material(root_node: Node, material_name: String, new_material: StandardMaterial3D) -> bool:
var updated = false
for mesh_instance in mesh_instances:
var mesh = mesh_instance.mesh
if mesh:
for i in range(mesh.get_surface_count()):
var current_material = mesh.surface_get_material(i)
if current_material and current_material.resource_name == material_name:
apply_material_with_queue(mesh_instance, i, new_material)
#mesh_instance.set_surface_override_material(i, new_material)
updated = true
#Log.pr("Updated material '%s' with pre-made material" % material_name)
return updated
# Helper function - find all mesh instances recursively
func find_all_mesh_instances(node: Node) -> Array[MeshInstance3D]:
if node is MeshInstance3D:
mesh_instances.append(node)
for child in node.get_children():
mesh_instances += find_all_mesh_instances(child)
return mesh_instances
# Helper function - update material in a specific mesh instance
func update_material_in_mesh_instance(mesh_instance: MeshInstance3D, material_name: String, new_color: Color) -> bool:
var updated = false
var mesh = mesh_instance.mesh
if mesh:
for i in range(mesh.get_surface_count()):
var material = mesh.surface_get_material(i)
if material and material.resource_name == material_name:
var new_material = material.duplicate()
new_material.albedo_color = new_color
mesh_instance.set_surface_override_material(i, new_material)
#Log.pr("Updated material '%s' to color: %s" % [material_name, new_color])
updated = true
return updated
func apply_material_with_queue(mesh_instance: MeshInstance3D, index: int, material: StandardMaterial3D):
ColorData.queue_material_application(mesh_instance, index, material)
return

View file

@ -0,0 +1 @@
uid://dmgn1sve22e8a

View file

@ -0,0 +1,19 @@
extends TreeColorDefault
func set_leaf_color(model_instance: Node3D):
find_all_mesh_instances(model_instance)
var material = ColorData.get_random_leaf_material(tree_name, current_season)
update_material_by_name_with_material(model_instance, "leafsGreen", material)
return
func set_trunk_color(model_instance: Node3D):
find_all_mesh_instances(model_instance)
var material = ColorData.get_random_trunk_material(tree_name, current_season)
update_material_by_name_with_material(model_instance, "woodBark", material)
return

View file

@ -0,0 +1 @@
uid://dk04iuaocilih

View file

@ -0,0 +1,19 @@
extends TreeColorDefault
func set_leaf_color(model_instance: Node3D):
find_all_mesh_instances(model_instance)
var material = ColorData.get_random_leaf_material(tree_name, current_season)
update_material_by_name_with_material(model_instance, "leafsGreen", material)
return
func set_trunk_color(model_instance: Node3D):
find_all_mesh_instances(model_instance)
var material = ColorData.get_random_trunk_material(tree_name, current_season)
update_material_by_name_with_material(model_instance, "woodBark", material)
return

View file

@ -0,0 +1 @@
uid://3flh70jpmq2w

View file

@ -0,0 +1,19 @@
extends TreeColorDefault
func set_leaf_color(model_instance: Node3D):
find_all_mesh_instances(model_instance)
var material = ColorData.get_random_leaf_material(tree_name, current_season)
update_material_by_name_with_material(model_instance, "leafsGreen", material)
return
func set_trunk_color(model_instance: Node3D):
find_all_mesh_instances(model_instance)
var material = ColorData.get_random_trunk_material(tree_name, current_season)
update_material_by_name_with_material(model_instance, "woodBark", material)
return

View file

@ -0,0 +1 @@
uid://bjsj2j01nmnfq

View file

@ -0,0 +1,19 @@
extends TreeColorDefault
func set_leaf_color(model_instance: Node3D):
find_all_mesh_instances(model_instance)
var material = ColorData.get_random_leaf_material(tree_name, current_season)
update_material_by_name_with_material(model_instance, "leafsDark", material)
return
func set_trunk_color(model_instance: Node3D):
find_all_mesh_instances(model_instance)
var material = ColorData.get_random_trunk_material(tree_name, current_season)
update_material_by_name_with_material(model_instance, "woodBark", material)
return

View file

@ -0,0 +1 @@
uid://de77441cemrqe

View file

@ -20,10 +20,6 @@ func set_tree_data(data: TreeDataResource):
tree_data = data
spawn_model()
func setup_tree(data: TreeDataResource):
# Alternative method name if you prefer
set_tree_data(data)
func spawn_model():
if not tree_data or not tree_data.model:
Log.pr("No tree data or model provided")
@ -37,7 +33,9 @@ func spawn_model():
# Instantiate the model from the TreeDataResource
model_instance = tree_data.model.instantiate()
tree_data.apply_seasonal_colors(model_instance, "spring")
add_child(model_instance)
# Create base circle after model is loaded
if not base_circle:
@ -45,6 +43,7 @@ func spawn_model():
# Re-scan for mesh instances in the new model
find_all_mesh_instances(model_instance)
update_outline_materials()
# Apply any additional properties from tree_data
@ -63,7 +62,7 @@ func apply_tree_properties():
var scale_variation = randf_range(0.8, 1.2)
model_instance.scale *= scale_variation
func setup_outline_material():
func setup_outline_material() -> void:
# Create outline material with your shader
outline_material = ShaderMaterial.new()
outline_material.shader = preload("res://outline.gdshader")