Squash the Creeps(First 3D Game) - Game Crashes When Implementing die() Function

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By bob152637485

I have been following along the 3D game tutorial pretty closely, but during the section where we implement killing the player, the game suddenly crashes every time I try to run it. I have narrowed it down to the die() function, specifically queue_free() being called to delete the player. After putting in some breakpoints and stepping through, what appears to be happening is that somehow, I think the very first mob spawns right on top of the player, killing the player right away. The next iteration of _on_MobTimer_timeout() then gets a Node not found error, due to trying to spawn another mob based off a player reference that no longer exists(I haven’t implemented the stopping of the timer yet).

I’ll put my code below, but I think I need to somehow prevent the mob from touching my player node right as the game is starting. Any help with this would be appreciated, especially if there is another issue altogether that I am missing. Thank you! PS, sorry for the bad code formatting, it seems that large blocks cause issues for some reason.

Main.gd:

`extends Node

#no different than exporting a normal variable, but in this case, it allows up to assign a scene
export (PackedScene) var mob_scene

func _ready():
randomize()

func _on_MobTimer_timeout():
# Create a new instance of the Mob scene.
var mob = mob_scene.instance()

# Choose a random location on the SpawnPath.
# We store the reference to the SpawnLocation node.
var mob_spawn_location = get_node("SpawnPath/SpawnLocation")
# And give it a random offset.
mob_spawn_location.unit_offset = randf()

#finds the center of the Player node's coordinates
var player_position = $Player.transform.origin
mob.initialize(mob_spawn_location.translation, player_position)

add_child(mob)

`

======================================================================

Mob.gd:

extends KinematicBody

signal squashed

Minimum speed of the mob in meters per second.

export var min_speed = 10

Maximum speed of the mob in meters per second.

export var max_speed = 18

var velocity = Vector3.ZERO

func _physics_process(_delta):
move_and_slide(velocity)

We will call this function from the Main scene.

func initialize(start_position, player_position):
# We position the mob and turn it so that it looks at the player.
look_at_from_position(start_position, player_position, Vector3.UP)
# And rotate it randomly so it doesn’t move exactly toward the player.
rotate_y(rand_range(-PI / 4, PI / 4))

# We calculate a random speed.
var random_speed = rand_range(min_speed, max_speed)
# We calculate a forward velocity that represents the speed.
velocity = Vector3.FORWARD * random_speed
# We then rotate the vector based on the mob's Y rotation to move in the direction it's looking.
velocity = velocity.rotated(Vector3.UP, rotation.y)

func _on_VisibilityNotifier_screen_exited():
queue_free()

func squash():
emit_signal(“squashed”)
queue_free()

=======================================================================

Player.gd:

extends KinematicBody

signal hit

How fast the player moves in meters per second.

export var speed = 14

The downward acceleration when in the air, in meters per second squared.

export var fall_acceleration = 75

Vertical impulse applied to the character upon jumping in meters per second.

export var jump_impulse = 20

Vertical impulse applied to the character upon bouncing over a mob in meters per second.

export var bounce_impulse = 16

var velocity = Vector3.ZERO

#similar to _process(delta), but runs at a fixed rate(60FPS by default), as opposed to as fast as the computer can do
#as the name implies, this is best for anything involving physics, like moving bodies and collision
func _physics_process(delta):
# input direction.
var direction = Vector3.ZERO

#update direction based off input
if Input.is_action_pressed("move_right"):
	direction.x += 1
if Input.is_action_pressed("move_left"):
	direction.x -= 1
if Input.is_action_pressed("move_back"):
	# Notice how we are working with the vector's x and z axes.
	# In 3D, the XZ plane is the ground plane.
	direction.z += 1
if Input.is_action_pressed("move_forward"):
	direction.z -= 1

#the look_at() function points the body in the specified direction, needing a reference to "up"
#translation, is the local location of the body relative to its parent's coordinates, rather than the global coordinates
if direction != Vector3.ZERO:
	direction = direction.normalized()
	$Pivot.look_at(translation + direction, Vector3.UP)

# Ground velocity
velocity.x = direction.x * speed
velocity.z = direction.z * speed

# Jumping.
if is_on_floor() and Input.is_action_just_pressed("jump"):
	velocity.y = jump_impulse

# Vertical velocity
velocity.y -= fall_acceleration * delta

# Moving the character
# this function makes for smoother movement if there were to be a collision.
# it takes a velocity and the up direction, and returns the leftover velocity after accounting for collisions
# in this case, it prevents the body from gaining enough momentum to clip through collisions
velocity = move_and_slide(velocity, Vector3.UP)

for index in range(get_slide_count()):
	# We check every collision that occurred this frame.
	var collision = get_slide_collision(index)
	# If we collide with a monster...
	if collision.collider.is_in_group("mob"):
		var mob = collision.collider
		# ...we check that we are hitting it from above.
		if Vector3.UP.dot(collision.normal) > 0.1:
			# If so, we squash it and bounce.
			mob.squash()
			velocity.y = bounce_impulse

func die():
#pass
emit_signal(“hit”)
queue_free()

func _on_MobDetector_body_entered(body):
die()

UPDATE: After some toying around, I believe the issue is the two different collision areas on the player scene. Initially, they overlapped with one another, causing the on_Mob_Detector_body_entered() function to be called right away. I separated them, and the game no longer crashes, but now the player doesn’t die when colliding with a mob.

bob152637485 | 2022-11-11 01:59

:bust_in_silhouette: Reply From: bob152637485

GOT IT! It’s always something simple. It would seem that I forgot to properly mask the MobDetector node, so it wasn’t detecting the mob layer, and only looking at the player layer instead.