Godot Version
4.6.1
Question
I currently have a system where a player can place a 3D item and pick it back up again. This has worked fine, so I decided to try to implement a system where the player can only place items where there is enough room. As such I created an Area3D with a collision box. This Area3D goes to where the player is about to place their item and checks if itself is colliding with anything, if it is, it aborts the placing of the item. This seemed simple enough to code in, but I have struggled to actually make it work.
There are so many weird issues with it sometimes working and other times not, the player being able to place an item ON THE AREA3D! I have explored collision masks/layers, but I’ve found them to behave odd as well, if I were to change the Area3D’s layer/mask where it can no longer be placed on, the Area3D will also no longer function as it won’t collide with other objects. I’ve also tried switching “monitoring” or “monitorable” on/off both in the editor and in the code and this doesn’t seem to help either.
The code for my player placing down an item is as follows:
func putdown():
if raycast.is_colliding():
raycastcollisionpoint = raycast.get_collision_point()
currentplayerrotation = $Pivot/Camera3D.global_rotation
$Area3D.global_position = raycastcollisionpoint
$Area3D.global_position.y = raycastcollisionpoint.y + 1.1
if $Area3D.has_overlapping_bodies():
return
elif $Area3D.has_overlapping_areas():
return
else:
emit_signal("sendraycastcollision",raycastcollisionpoint,currentplayerrotation)
The code for my raycast that check the position of where the player wants to place an item:
func pickup():
# if not colliding, go back
if !raycast.is_colliding():
return
print ("raycast hit something")
print(str(raycast.get_collider()))
# get what raycast is hitting, otherwise nothing spefic can happen
var obj = raycast.get_collider()
# if object is collidable but is NOT in group "items", its not an item, ignore
if !obj.is_in_group("items"):
print (str(obj) + " is not an item")
return
print ("this is an item")
# if object is collidable AND in group "items" but does NOT have a "func picked_up():" code, ignore (failsafe)
if !obj.has_method("picked_up"):
print ("can't pick this up as no function to pick up!")
return
print(obj.name)
# call "func picked_up():" on the object
obj.picked_up()
print (str(obj) + " is an item")
I’ve also linked a video which shows the problem in MUCH greater detail here: