Picking up Object?

Godot Version

4.2.2

Question

Hello all,

I am trying to recreate something I did in Unity years ago in 2D and doing that requires that my character pick up an item and then drop/throw it. The first part through is where I am having the problem right now picking up the item.

The idea is this press the “P” button on the keyboard and if the canPickUp var is true on the player and you are next to it then pick it up. By doing so the the item is magically given the global co-ordinates of the player so it will appear in the player.

Now I found a tut that did just this, but, it was for Godot3 I think and it wasn’t long before it didn’t work so I tried modyfying what I could to get it working, but, kept getting weird (I before E except after weird) results. And I have two bombs in the game scene.

So the object to pickup is designed like this:

Why we needed 2 collisions shapes has me confused probably because the first one is a for rigidbody2D, but lost me straightaway.

The only thing added to the player script was this:

#var to pick up bomb
var canPickUp = true;
#---------------------

And this is the Object code in it’s entirety:

extends RigidBody2D

#get access to player (hero)
@onready var player = $"../Player"
@onready var area = $Area2D

#vars
var picked = false;


func _physics_process(delta):

	#deviated from tut getting the coordintes for the player sprite
	#and not a positional node like he did
	if(picked == true):
		print("picked is true");
		var posX = player.global_position.x;
		var posY = player.global_position.y;
		var posVector = Vector2(posX,posY)
		self.global_position = posVector;
		print (posVector);
	#pass


#to pickup the bomb
func _input(event):
	#pickUp action
	if(Input.is_action_just_pressed("pickUp")):
		var bodies = area.get_overlapping_bodies();
		for body in bodies:
			print(body);
			if( (body.name == "Player") and (player.canPickUp == true) ):
				print("...conditions true...");
				picked = true;
				player.canPickUp = false;

Now, I know that the bodies are being printed but they aren’t correct as the bodies of both “bombs” (objectToGrabX - don’t ask) are being printed out and they can’t possibly both be considered overlapping they aren’t anywhere near each other. For instance pushing the “P” next to one of the bombs give me this in the log window:

ObjectToGrab1:<RigidBody2D#42983229133>
TileMap:<TileMap#39929775354>
ObjectToGrab2:<RigidBody2D#42899343048>
TileMap:<TileMap#39929775354>

And this line:

if( (body.name == “Player”) and (player.canPickUp == true) ):

Isn’t functioning either as words “conditions true” never gets printed and the physics_process that relies on picked equalling true never gets processed either. In fact, I don’t understand the whole body equalling Player is all about.

So, I am a bit stuck on the code and can’t see a solution.

As always, if anyone can help here is a big “thankyou” in advance.

Regards.

1 Like

from this print, you can see that no body that’s named as Player detected as a body inside the area2d
hence why the "...conditions true..."never printed. because there’s no body detected that’s named Player

show your player scene tree

The player should be at least one of the items in the overlapping area as it’s standing right next to the objectToGrab (ie bomb). Even though it was the code from an “older” tutorial, I went looking to see if was still current and/or valid and overlapping bodies is in Godot 4 documentation. So, as far as I know hasn’t been deprecated.

I checked with code in another spot and the body.name is definitely “Player”. In any case here is the scene tree of player.

“Player” is top left.

Does that help at all?

may i see your collectible’s area2d’s collision mask?
like in here:
image

Damn that was quick it 6am down here need more sleep.

Ok, the “AREA” mask is here:

pickup_prob3

I can’t say up any longer I need to go back to bed.

Regards.

yes that mask should make the “2” enabled too
not just “1”

mask is like in which layer you will detect, since the Player is on Layer “2”, you will need Mask “2” to be on too to detect the Player that’s on Layer “2”

Yep, that was definitely the problem :grin:. Thankyou for that!!!

I’ve always had problem with collisions in Unity and Unreal, just never got to grips with them and now with Layers and masks - making it worse. I was playing around with the collisions on the first node, never even thought of going down deeper

But now I have another problem as soon as I pick up the object. I don’t think I would be able to explain, what it is. You need to see it :rofl:. I’ll try and get OBS running to record it and post to YouTube. It’s not a program I understand very well, so this may take a little while.

Regards.

Like I said, it took some time OBS doesn’t like me very much.

Found a free video editor to remove the first part.

https://youtu.be/eAj5n-XXsBA

i have a news for you, because you are using rigidbody2d, trying to set position of rigidbody require you to integrate forces

so the position in physics server in sync with the current node position

OR

what else you can do is, you can freeze the bomb and reparent the bomb to the player’s node.
you can see how freeze works on pick up item here:

with this method, you dont need to set the bomb position following the player position in physics process code, because it’s already parented as a child in the player node

1 Like

Whoa! That is going to take some time to get through.

I had no idea it was going to be so complex - I thought all I would need to do would be change the mass.

But if I want the player to carry the object and drop/throw it I better get going through these two solutions.

Seeing as you have a greater understanding of what is going on what solution would you suggest for my needs?

Regards.

the freeze and reparent solution should be the solution for picking up item, if it’s a rigidbody type item

if you dont want to mess with physics server calculation, you can use characterbody2d for the bomb, as it already has simplified version for the physics with move_and_slide() or move_and_collide() in its _physics_process

1 Like

I remember what you said about not really needing a Rigidbody 2d for a simple platformer, so, in the shower I was thinking about just using a simple Area2D for the bomb. Should be the easiest of the lot. So far, I have the code for picking it up and have it move around with me. And no bouncing around the screen, a bonus. But you can pass right behind the object - but, I can live with that. Next I’ll try and dream up the code to drop it, should be interesting, head scratching and hair losing :grin:. And then and only then the hard part starts.

If this fails I might try as you say and turn it into a character, that might be the smartest option of the lot.

Again thankyou for all your help! It has been invaluable to me :grinning: :grinning: :grinning:.

The brewskis are on me :beers:.

1 Like

Just in case anyone reads this - the area 2D idea did work. It wasn’t perfect as I wasn’t able to throw the “bomb”, but, I think with the game such as this placing the bomb manually was the better option.