fix: empty 3x3 tiles below candy cannon and add outline shaders to cannon, projectiles, bubbles and vfx

This commit is contained in:
2026-06-29 20:53:28 +08:00
parent 37c179a9e1
commit a5595dbd6b
2 changed files with 51 additions and 7 deletions
+35 -2
View File
@@ -9,7 +9,38 @@ class_name CandyCannonController
@onready var tank = $Tank if has_node("Tank") else null
func _ready() -> void:
pass
_apply_outline_recursive(self)
func _apply_outline_recursive(node: Node) -> void:
if node is MeshInstance3D and node.mesh:
# Some procedural meshes might not have get_surface_count or it might be 1.
# If the mesh has material_override, apply outline to that
if node.material_override and node.material_override is StandardMaterial3D:
var mat = node.material_override
if not mat.next_pass:
var outline_mat = ShaderMaterial.new()
outline_mat.shader = load("res://assets/shaders/outline3d.gdshader")
mat.next_pass = outline_mat
else:
for i in range(node.mesh.get_surface_count()):
var mat = node.get_active_material(i)
if mat:
if not mat.next_pass:
var unique_mat = mat.duplicate()
var outline_mat = ShaderMaterial.new()
outline_mat.shader = load("res://assets/shaders/outline3d.gdshader")
unique_mat.next_pass = outline_mat
node.set_surface_override_material(i, unique_mat)
if node is GPUParticles3D and node.draw_pass_1 and node.draw_pass_1.material:
var mat = node.draw_pass_1.material
if not mat.next_pass:
var outline_mat = ShaderMaterial.new()
outline_mat.shader = load("res://assets/shaders/outline3d.gdshader")
mat.next_pass = outline_mat
for child in node.get_children():
_apply_outline_recursive(child)
func _process(delta: float) -> void:
if ring1: ring1.rotate_y(delta * 1.5)
@@ -42,7 +73,8 @@ func spawn_projectile(target_world_pos: Vector3, duration: float) -> void:
mat.emission_energy_multiplier = 3.0
projectile.material_override = mat
get_tree().get_root().add_child(projectile)
projectile.top_level = true
add_child(projectile)
# Start projectile slightly above the cannon center
projectile.global_position = global_position + Vector3(0, 3.0, 0)
@@ -75,6 +107,7 @@ func spawn_projectile(target_world_pos: Vector3, duration: float) -> void:
particles.amount = 16
particles.lifetime = 0.4
projectile.add_child(particles)
_apply_outline_recursive(projectile)
tween.set_parallel(true)
tween.tween_property(projectile, "global_position:x", target_world_pos.x, duration).set_trans(Tween.TRANS_LINEAR)
+16 -5
View File
@@ -412,11 +412,11 @@ func _apply_arena_setup() -> void:
var pos = Vector2i(x, z)
# Center 3x3 block: NPC obstacle (Candy Pump)
if _is_npc_zone(pos):
# Make the floor walkable visually instead of obstacle red
gridmap.set_cell_item(Vector3i(x, 0, z), TILE_WALKABLE)
gridmap.set_cell_item(Vector3i(x, 1, z), -1)
continue
if _is_npc_zone(pos):
# Make the floor empty (-1) beneath the Candy Pump
gridmap.set_cell_item(Vector3i(x, 0, z), -1)
gridmap.set_cell_item(Vector3i(x, 1, z), -1)
continue
# Boundary walls: perimeter (row 0, row 19, col 0, col 19)
if x == 0 or x == ARENA_COLUMNS - 1 or z == 0 or z == ARENA_ROWS - 1:
@@ -982,6 +982,12 @@ func _spawn_impact_particles(targets: Array) -> void:
spatial_mat.emission_enabled = true
spatial_mat.emission = Color(1.0, 0.6, 0.8)
spatial_mat.emission_energy_multiplier = 2.0
# Outline shader for splash VFX
var outline_mat = ShaderMaterial.new()
outline_mat.shader = load("res://assets/shaders/outline3d.gdshader")
spatial_mat.next_pass = outline_mat
mesh.material = spatial_mat
particles.draw_pass_1 = mesh
@@ -1558,6 +1564,11 @@ func _spawn_bubble_visual(center: Vector2i) -> void:
mat.emission_enabled = true
mat.emission = Color(1.0, 0.2, 0.6)
mat.emission_energy_multiplier = 1.5
var outline_mat = ShaderMaterial.new()
outline_mat.shader = load("res://assets/shaders/outline3d.gdshader")
mat.next_pass = outline_mat
mesh_inst.material_override = mat
var main = get_node_or_null("/root/Main")