Just had a thought, the zombie.gd
script is not attached to the parent node in the zombie_road_block.tscn
packedscene. Could this be why zombie_road_block.vehicle = vehicle
can’t find vehicle
because it’s expecting vehicle to be defined in the parent node of zombie_road_block.tscn
packedscene?
If so, what method and syntax do I need to reference zombie.gd
which is a child of zombie_road_block_scene?
Thanks so much y’all for any help or tips. Cheers!
EDIT:
I attempted to get_node on each zombie (also named them “zombie_a” “zombie_b” “zombie_c” to make it more clear) and then set the vehicle var (which is undefined in the zombie.gd script attached) thinking this would set the var once the zombies are instantiated but doesn’t seem to make a difference, is this a good method and I just got a detail wrong, or is there another method I should use to make sure the vehicle var is set correctly in the children of the instantiated packedscene?
current zombie.gd
extends CharacterBody3D
@export_group("Zombie Stats")
@export var movement_speed: float = 4.0
@export var Health = 1
##Zombie was referencing the vehicle node that contained the model, changed so now it uses the model global position.
#@onready var vehicle = $"Vehicle_parent/Fiesta_vehicle"
#@onready var sfx_zombie_run_over = $"../sfx_zombie_run_over"
#@onready var zombies_killed_label = get_node("hud/Score/Zombies_Killed/zombies_killed_label")
@onready var nav_agent: NavigationAgent3D = get_node("NavigationAgent3D")
@onready var idle_Label3D = $"idle_Label3D"
@onready var pursue_Label3D = $"pursue_Label3D"
@onready var attacking_Label3D = $"attacking_Label3D"
var vehicle
signal zombie_killed
enum State {IDLE, PURSUE, MELEE_ATTACK}
var current_state: int = State.IDLE
func _physics_process(delta):
process_state(delta)
func process_state(delta):
match current_state:
State.IDLE:
idle_Label3D.visible = true
pursue_Label3D.visible = false
attacking_Label3D.visible = false
if is_target_in_range(10.0):
current_state = State.PURSUE
State.PURSUE:
idle_Label3D.visible = false
pursue_Label3D.visible = true
attacking_Label3D.visible = false
move_towards_target(delta)
if is_target_in_attack_range():
current_state = State.MELEE_ATTACK
State.MELEE_ATTACK:
idle_Label3D.visible = false
pursue_Label3D.visible = false
attacking_Label3D.visible = true
if is_target_in_attack_range():
melee_attack()
else:
current_state = State.PURSUE
func is_target_in_range(range: float) -> bool:
var distance_to_target = global_transform.origin.distance_to(vehicle.global_transform.origin)
return distance_to_target <= range
func is_target_in_attack_range() -> bool:
var distance_to_target = global_transform.origin.distance_to(vehicle.global_transform.origin)
return distance_to_target <= 3.0 # Adjust the attack range as needed
func move_towards_target(delta):
var direction = vehicle.global_transform.origin - global_transform.origin
direction = direction.normalized()
velocity = lerp(velocity, direction * movement_speed, delta)
move_and_slide()
func melee_attack():
emit_signal("deal_melee_damage")
print("Melee attack on the vehicle!")
## Bullet damage logic
func Hit_Successful(Damage, _Direction: Vector3 = Vector3.ZERO, _Position: Vector3 = Vector3.ZERO):
Health -= Damage
if Health <= 0:
zombie_killed.emit()
queue_free()
print("zombie shot")
## Collision damage logic
func _on_body_entered() -> void:
zombie_killed.emit()
$"../sfx_zombie_run_over".play()
queue_free()
print("zombie ran over")
current main_scene.gd
extends Node3D
#@onready var vehicle = $Vehicle
@onready var hud = $hud
#@onready var vehicle_vehicle = $"../Vehicle/vehicle"
@onready var sfx_zombie_run_over = $"sfx_zombie_run_over"
@onready var zombies_killed_label = get_node("hud/Score/Zombies_Killed/zombies_killed_label")
#@onready var vehicle = %vehicle
@onready var vehicle = $"Vehicle_parent/Fiesta_vehicle"
var zombie_road_block_scene = preload("res://assets/zombie_road_block.tscn").instantiate()
func _ready():
print(vehicle)
#print(vehicle_vehicle)
func hud_increase_zombie_killing_count_method():
$hud._on_zombie_killed()
func on_vehicle_health_changed():
$hud._on_fiesta_hit_points_update()
func _physics_process(delta):
get_tree().call_group("Enemies", "update_target_location", vehicle.global_transform.origin)
func _on_zombie_spawner_area_3d_vehicle_entered_zombie_spawner():
print("_on_zombie_spawner_area_3d_vehicle_entered_zombie_spawner called")
# Spawn road blocks
var progress_step = 1.0 / 10.0 # Divide the range of progress ratios into 10 equal parts
var current_progress = 0.0 # Start at the beginning of the path
for i in range(10): # Spawn 10 road blocks
var zombie_road_block = zombie_road_block_scene.instantiate()
zombie_road_block.get_node("zombie_a").vehicle = vehicle
zombie_road_block.get_node("zombie_b").vehicle = vehicle
zombie_road_block.get_node("zombie_c").vehicle = vehicle
var road_block_spawn_location = get_node_or_null("ZombieSpawnPath/ZombieSpawnLocation")
if road_block_spawn_location:
print("Spawn location found: ", road_block_spawn_location.global_transform.origin)
else:
print("Spawn location not found!")
# Set the vehicle reference for each zombie and connect signals
for zombie in zombie_road_block.get_children():
if zombie.is_in_group("Enemies"):
zombie.vehicle = vehicle
zombie.zombie_killed.connect(sfx_zombie_run_over.play)
zombie.zombie_killed.connect(hud.hud_increase_zombie_killing_count_method)
# Assign a progress ratio from one of the 10 equal parts with some randomness
road_block_spawn_location.progress_ratio = current_progress + randf() * progress_step * 0.5
# Add a small random offset
var offset_x = randf_range(-0.1, 0.1)
var offset_z = randf_range(-0.1, 0.1)
road_block_spawn_location.position.x += offset_x
road_block_spawn_location.position.z += offset_z
# Generate a random rotation angle in degrees, excluding 330-30, 60-120, 150-210, and 240-300 degrees
var random_rotation_degrees
while true:
random_rotation_degrees = randi() % 360
if (random_rotation_degrees >= 30 and random_rotation_degrees < 60) or \
(random_rotation_degrees >= 120 and random_rotation_degrees < 150) or \
(random_rotation_degrees >= 210 and random_rotation_degrees < 240) or \
(random_rotation_degrees >= 300 and random_rotation_degrees < 330):
break
# Convert the rotation angle to radians
var random_rotation = deg_to_rad(random_rotation_degrees)
# Create a Transform3D with the random rotation
var transform = Transform3D()
transform = transform.rotated(Vector3.UP, random_rotation)
transform.origin = road_block_spawn_location.global_transform.origin
zombie_road_block.global_transform = transform
var zombies = [
zombie_road_block.get_node("zombie_a"),
zombie_road_block.get_node("zombie_b"),
zombie_road_block.get_node("zombie_c")
]
for zombie in zombies:
zombie.scale = Vector3(0.13, 0.13, 0.13)
var roadblock = zombie_road_block.get_node("roadblock")
roadblock.scale = Vector3(1, 1, 2.635)
add_child(zombie_road_block)
# Move to the next part of the progress range for the next road block
current_progress += progress_step