Godot Version
4.4.1-stable win64
Question
Im trying to make a mechanic where the player can hold "boxes" and drop them somewhere else, i did this by reparenting the "box" to the player and sending a signal to the "box" so it freezes the rigidbody and disables the colision of its child but when it is dropped it goes to the place its supposed to but the phisics arent reenabled and it floats without colision
The related player script
if Input.is_action_just_pressed("interact"):
interact()
move_and_slide()
func interact() -> void:
if not get_meta("carrying"):
for overlapped_body in $Interact_area.get_overlapping_bodies():
if overlapped_body.is_in_group("grab_items"):
set_meta("carried", overlapped_body)
$test_text.text = str(get_meta("carried"))
get_meta("carried").call_deferred("grabed")
get_meta("carried").reparent($Player_colision, true)
get_meta("carried").position = $Hold_point.position
set_meta("carrying", true)
elif get_meta("carrying"):
$test_text.text = str("Droped")
get_meta("carried").position = $Drop_point.position
get_meta("carried").reparent($"..", true)
get_meta("carried").call_deferred("dropped")
set_meta("carrying", false)
set_meta("carried", null)
await get_tree().create_timer(0.1).timeout
The script of the box
extends RigidBody2D
var carried = false
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
freeze = carried
$Item_colision.disabled = carried
func grabed() -> void:
carried = true
freeze = carried
$Item_colision.disabled = carried
func droped() -> void:
carried = false
freeze = carried
$Item_colision.disabled = carried
(Edit)
I fixed it. Found a post with code that fixed it
Here is what i wrote to solve it
if Input.is_action_just_pressed("interact"):
if held_object:
drop_object()
else:
grab_object()
move_and_slide()
func grab_object() -> void:
# Creates an array with all bodies currently overlapping with the Area2D. Make sure the collision layers and masks are set up correctly, so the Area2D only detects throwable objects and nothing else.
var objects_in_range :Array = $Interact_area.get_overlapping_bodies()
# if there's at least one object:
if objects_in_range:
# Picks up the first object in the array. In case there's more than one object in range, you might wanna add some sorting logic.
held_object = objects_in_range[0]
# stores the object's current parent to return it later
held_objects_parent = held_object.get_parent()
# Makes the object a child of this CharacterBody2D. This isn't needed for accessing it, but to make its position relative to the player's position.
held_object.reparent(self)
held_object.position = $Hold_point.position
# prevents it from moving on it's own
held_object.freeze = true
func drop_object() -> void:
held_object.position = $Drop_point.position
# returns the object to it's original parent and allows it to move on it's own again
held_object.reparent(held_objects_parent)
held_object.freeze = false
# Empties 'held_object', so you can pick up another object.
held_object = null