- Home /
How to select the trigger layer on a Box Collider 2D
While making an Item system for my game (In which you can drop and pick up different Items) I encountered a problem when trying to make the item not clip through the ground but still act as a trigger for the player to collide with it and be able to "pick up" the item.
The BoxCollider 2D on trigger check makes it so that the collider only serves as a trigger when detecting a collision but ignores actually colliding and thus clips through other colliders.
So I'm kind of stuck here. How do I make it so that the Item stays on the ground and that the player and other items can pass through it?
Answer by Chubzdoomer · Sep 19, 2021 at 10:39 PM
I'm assuming this is a common problem because I ran into the same thing in the platformer I'm working on. In my case, I wanted to have physics variants of my collectibles that bounced off the ground instead of hovering mid-air, but I also still wanted the player to interact with them via a trigger instead of a collision.
The solution I came up with was simple:
Keep your "base" object exactly like it is, and create an empty (child) Game Object underneath it. I named my child object "Solid Collider" to make it clear what its purpose was, but you can name yours whatever you want.
Next, (1.) give your child a Box Collider with the same dimensions as the parent's collider (and be sure "Is Trigger" is NOT checked), and (2.) assign your child object to a layer that only handles ground collisions.
In case you aren't familiar with layers, they basically let you determine which OTHER layers an object can collide with. To assign a layer to an object, click the "Layers" dropdown box in the upper-right corner of the Inspector. To specify which layers your selected layer interacts with, modify the collision matrix located at the very bottom of Edit->Project Settings->Physics 2D (be sure to click "Physics 2D," and not "Physics"!).
In my game for example, my ground tiles/objects are assigned to a "Ground" layer that interacts with most other layers, and my physics collectibles' (solid) child object is assigned to a "Ground Col Only" layer that literally ignores every layer BUT the Ground layer, meaning the collectibles will pass right through colliders belonging to enemies, random objects, etc. and will only ever bounce off the ground.
Here's a simple example of how each of my physics collectibles is structured in the heirarchy:
Base Object [Trigger Collider -- Default Layer]
----> Child Object [Solid Collider -- "Ground Col Only" Layer]
There may be an even better method out there, but this has worked quite well for me and is really easy to set up. Try it out and let me know how it works for you. Hope this helps!
Answer by MKGPlayz · Sep 19, 2021 at 11:44 PM
I think this solution works but I'm not sure...
Basically, I lauch a ray using the Return_RayCast(); function I made. Then we turn the body into a static object. I don't know if this is what you wished having like answer but here it is anyways. Feedback would be appreciated!
Code:
using UnityEngine;
public class PickupGrounded : MonoBehaviour
{
Rigidbody2D rb;
[Header("Global Variables")]
[SerializeField] Transform orgin;
[SerializeField] float distance;
[SerializeField] LayerMask lm;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
//Says if isGrounded
bool isGrounded = Return_RayCast();
//Changes the gravity scale & body type
rb.gravityScale = isGrounded ? 0 : 1;
rb.bodyType = isGrounded ? RigidbodyType2D.Static : RigidbodyType2D.Dynamic;
}
//This boolean will be used to return if the object is on the ground or not
protected bool Return_RayCast()
{
return Physics2D.Raycast(origin: orgin.position, direction: Vector2.down, distance, lm);
}
}
So I did some testing on the script and I can say that it works. I'll give you the values that I used for my extensive testing.
Global Values Origin [Your Object] Distance [0.3f to 0.4f] <== choose your favorite value LM [Your LayerMask]