Instances fall more than once

Godot Version

v4.2.2

Question

I’m trying to make a simple stacking game. When one ingredient falls and the mouse is clicked, it’s supposed to fall quicker. However, more than one instance at a time falls when it receives the mouse input.

I have tried to use ray casting so that the ingredient that is the closest to the bread will fall quicker when clicked but it only works on the first ingredient.

Send help. All help is appreciated :slight_smile:

without raycasting
ezgif-3-4389387418

#stack.gd - without raycasting:

extends Node

@onready var cheese_scene = preload("res://objects/cheese.tscn")
@onready var timer = $Timer

# Constants
const NEW_CHEESE_POSITION = Vector3(0, 6.06, 0)  # Position to spawn new cheese

var cheese_queue = []  # Queue to store cheese instances

func _ready():
	timer.connect("timeout", Callable(self, "_on_timer_timeout"))
	timer.start()

func _on_timer_timeout():
	spawn_new_cheese()

func spawn_new_cheese():
	var new_cheese = cheese_scene.instantiate()
	new_cheese.global_transform.origin = NEW_CHEESE_POSITION
	add_child(new_cheese)
	cheese_queue.append(new_cheese)
	new_cheese.connect("cheese_fell", Callable(self, "_on_cheese_fell"))
	update_cheese_clickability()

func update_cheese_clickability():
	for cheese in cheese_queue:
		cheese.can_be_clicked = false  # Disable all cheeses from being clicked
	if cheese_queue.size() > 0:
		cheese_queue[0].can_be_clicked = true  # Enable the oldest cheese to be clicked

func _on_cheese_fell():
	if cheese_queue.size() > 0:
		cheese_queue.pop_front()  # Remove the oldest cheese from the queue
		update_cheese_clickability()

#cheese.gd 
extends RigidBody3D

# Constants
const INITIAL_GRAVITY = Vector3(0, -0.5, 0)  # Even slower initial gravity
const FAST_GRAVITY = Vector3(0, -30.0, 0)    # Fast gravity when clicked

var initialGravitySet = false  # Flag to track if initial gravity is set
var fastFall = false  # Flag to track if fast falling is enabled
var can_be_clicked = false  # Flag to track if this cheese can be clicked

signal cheese_fell  # Signal to notify when the cheese falls fast

# Called when the node enters the scene tree for the first time.
func _ready():
	set_physics_process(false)  # Disable physics process until falling starts

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _physics_process(delta):
	if initialGravitySet:
		if fastFall:
			# Apply fast gravity
			linear_velocity += FAST_GRAVITY * delta
		else:
			# Apply initial slow gravity
			linear_velocity += INITIAL_GRAVITY * delta

# Handle mouse input
func _input(event):
	if can_be_clicked and event is InputEventMouseButton:
		var mouse_event = event as InputEventMouseButton
		if mouse_event.button_index == MOUSE_BUTTON_LEFT and mouse_event.pressed:
			if not initialGravitySet:
				set_initial_gravity()
			enable_fast_fall()

# Set initial slow falling speed
func set_initial_gravity():
	initialGravitySet = true
	set_physics_process(true)  # Enable physics process to update falling

# Enable fast falling speed
func enable_fast_fall():
	fastFall = true
	emit_signal("cheese_fell")  # Emit signal when the cheese falls fast

#timer.gd:
#not needed

extends Timer

func _ready():
	wait_time = 0.5  
	start()  

It would be more helpful to paste the scripts into the forum, using code formatting like so

```
type or paste code here
```

You can create these three ticks by pressing the </> button or ctrl+e

Seems like your timer.gd and stack.gd are both spawning ingredients. Could you describe what you expect to happen? how the game flows?

Thank you for the advice! I’m new. Sorry I thought I’d be too long. I have updated it now.

Thanks for replying! My bad, the timer function to spawn the ingredients is not needed. It was just used for testing. In the version with ray casting it works similarly but it spawns the ingredients in the main script.
The gameplay is intended to be very simple:

  1. Ingredients fall slowly from the sky at Vector3(0, 6.06, 0)

  2. Ingredients spawn every 0.5 seconds

  3. The left mouse button is clicked so that the ingredient (the oldest instance) falls at a faster pace

  4. It lands on the bread

Therefore, only one instance of the ingredient is allowed to take the mouse input

The issue is that when the left mouse button is clicked, all the instances that spawn takes the mouse input.

Let me know if you need to know anything else.

I would use the cheese_queue to track which is clickable by index. The input should be handled by the stack.gd

var cheese_queue = []  # Queue to store cheese instances
var cheese_click_index: int = 0

func _input(event: InputEvent) -> void:
	if event is InputEventMouseButton:
		cheese_queue[cheese_click_index].enable_fast_fall()
		cheese_click_index += 1

func _on_cheese_fell():
	if cheese_queue.size() > 0:
		if cheese_queue[cheese_click_index].fastFall:
			cheese_click_index -= 1
		cheese_queue.pop_front()  # Remove the oldest cheese from the queue
		update_cheese_clickability()
1 Like

Thank you for the suggestion! It works! Here is a result of your kind efforts. Thank you so much you saved me a lot of time of pain. :smiley:

thank u

1 Like

that’s one green sandwhich!

1 Like

gotta get that fibre :joy:

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.