I am trying to create pickups, that appear after an enemy dies, and that the player can pick up, but I am running into some issues.

First of all, I want the pickups to be affected by gravity, so I need a rigidbody2d and a boxcollider2d (non-trigger), so this works.

enter image description here

Now, if I want to collect the pickups on contact, I need to make the layers for the loot and the player get in contact, so that they can interact.

enter image description here

Now, of course, I do not want to push the pickups around. I want to actually pick them up when I touch them, but the collider is not a trigger so I thought I would use OnCollisionEnter to handle this.

        void OnCollisionEnter2D(Collision2D other)
            var loot = other.gameObject.GetComponent<ILoot>();

            loot?.PickUp(gameObject); // Destroys also the pickup

While this works, I am still using a non-trigger collider, which means that there are some physics effects that are not desired. For instance, when I "jump" onto the pickups.

enter image description here

Notice the subtle, but still present, slowdown in the fall, when the player enters in touch with the pickups?

How could I solve this issue??


Set the pickup to be on a layer that interacts with the ground only, not the player character.

Give your player character a child object that represents their collection radius. Give it a trigger collider, and set just this child object to be on a layer that interacts with the pickups, leaving the root of your player character on its original layer.

Now your player character will get OnTriggerEnter2D messages when they walk close enough for their child trigger collider to touch the pickups' solid colliders, but your player can still pass through the pickups because they don't interact with the player's solid collider.

As a bonus, you can use this child object to precisely control the pick-up radius independent of your character's normal collision size, or implement buffs like magnetically attracting pickups from further away.

  • \$\begingroup\$ Does this mean that I have to use 2 layers ("pickup object", and "pickup picker") for this mechanic alone? \$\endgroup\$ – Enrique Moreno Tent Jul 3 '20 at 11:55
  • \$\begingroup\$ That is an option. It is not required that these layers be exclusive to this one mechanic. \$\endgroup\$ – DMGregory Jul 3 '20 at 11:59
  • \$\begingroup\$ If you're already at your limit for physics layers, you can get rid of your "player trigger radius" layer/child object, and replace it with a Physics2D.OverlapCircleNonAlloc() query to scan a radius around the player for pickups to collect each frame. \$\endgroup\$ – DMGregory Jul 3 '20 at 12:16
  • \$\begingroup\$ I guess thats a good alternative... The layer system in Unity irks me, for some reason \$\endgroup\$ – Enrique Moreno Tent Jul 3 '20 at 15:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.