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.