print statement fixes bug?

Godot Ver: v4.5.1

Hello all.

This is my first post so bare with me if I make any mistakes.

I’m a very new developer working with the godot engine and I am attempting to make a basic pickup and throw system using a character body 2D (the player) and a rigid body 2D (the item | I want it to bounce of walls and experience collisions and whatnot). However, I have been having major issues with the “throwing” aspect of it.

picking up the item is fine and it works exactly as expected. However, Once I throw the item, the no matter where I am in the game world, the item first teleports to the LAST location that I picked it up from and THEN impulses. I genuinely have no idea why it’s doing this. The weirdness part is that it works completely fine when I use a print statement? I’ve tried looking at await process frame and freeze, set deferred and those kind of things but I’ve got nothing, so I just reverted back to my first draft of code.

Here is my entire code for player.gd so far:


extends CharacterBody2D

@export var speed: float = 300.0
@export var handle_distance: float = 45.0
@export var handle_smoothness: float = 0.35
@export var throw_power: float = 300.0

var current_item: RigidBody2D
var current_item_handle_lock_enabled := false
var pickup_debounce_time: float = 2.0
var pickup_debounce_tick: float = 0.0

const ITEM_LAYER: int = 8

@onready var pick_up_region: Area2D = $PickUpRegion
@onready var handle: Marker2D = $Handle
@onready var throw_audio: AudioStreamPlayer2D = $ThrowAudio


func _ready() -> void:
	pickup_debounce_tick = pickup_debounce_time


func _physics_process(delta: float) -> void:
	## handle movement. ##
	var movement_direction = Input.get_vector("move_left", "move_right", "move_up", "move_down")
	velocity = movement_direction * speed
	move_and_slide()

	## update handle position ##
	var mouse_position = get_global_mouse_position()
	var mouse_direction = global_position.direction_to(mouse_position)

	var prev_handle_position = handle.global_position
	var next_handle_position = global_position + (mouse_direction * handle_distance)

	handle.global_position = lerp(prev_handle_position, next_handle_position, handle_smoothness)

	## hold current item ##
	if current_item and current_item_handle_lock_enabled:
		collision_mask &= ~ITEM_LAYER

		current_item.global_position = handle.global_position
		print(current_item.global_position)

	## throw current item ##
	if Input.is_action_just_pressed("throw_item"):
		if current_item:
			current_item_handle_lock_enabled = false

			var throw_direction = global_position.direction_to(mouse_position)
			var throw_force = throw_direction * throw_power

			current_item.global_position = handle.global_position
			current_item.apply_impulse(throw_force)
			current_item = null

			pickup_debounce_tick = 0
			throw_audio.play(0.22)

	## update debounce ##
	pickup_debounce_tick += delta


func _on_pick_up_region_body_entered(body: Node2D) -> void:
	## detect an item within range ##
	if pickup_debounce_tick < pickup_debounce_time:
		return

	if body is RigidBody2D and body.name.to_lower() == "item":
		if !current_item:
			current_item = body
			current_item_handle_lock_enabled = true

it’s this part:

## hold current item ##
	if current_item and current_item_handle_lock_enabled:
		collision_mask &= ~ITEM_LAYER

		current_item.global_position = handle.global_position
		-->>> print(current_item.global_position) <<<--

with it, the code works fine. without it, then it doesn’t.

When using rigid bodies you can’t change their transform freely because that will de-sync it from the physics world and create issues like the one you are seeing.

You’ll need to implement the teleport in its RigidBody2D._integrate_forces() and change its position in the state parameter PhysicsDirectBodyState2D.transform