- Home /
how to distinguish which layer has been detected with OnTriggerEnter2D first?
Hey All,
I am trying to use layermasks with void OnTriggerEnter2D
Currently, in my Game, I will have 3 gameObjects sitting stacked on top of each other:
GO1: BigResource
GO2: SmallResource
GO3: Plot
Each game object has a layer allocated to them based on the naming above.
Using a boxCollider2D and OnTriggerEnter2D, I want to detect the following:
If GO1: BigResouce exists first if it does, I don't want to collider to detect the other 2 GO underneath it.
If GO1: BigResouce does not exist, then the boxCollider2D and OnTriggerEnter2D should detect GO2: Small Resource.
If GO2: BigResouce does not exist, then the boxCollider2D and OnTriggerEnter2D should detect GO3: Plot.
Else Do nothing
Below is my code:
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.CompareTag("Player"))
{
if (collision.gameObject.layer == LayerMask.NameToLayer("BigResource"))
{
Debug.Log("Hit a Big Resource");
}
else if (collision.gameObject.layer == LayerMask.NameToLayer("SmallResource"))
{
Debug.Log("Hit a Small Resource");
}
else if (collision.gameObject.layer == LayerMask.NameToLayer("Plot"))
{
Debug.Log("Hit a plot");
}
}
}
Are you able to advise what I am doing wrong?
Thank you
MegaTDog
(Anthony)
Note: I was using a raycast before to do this, which was working however I decided I didn't want to use a raycast anymore due to the way I want this system to work. My system needs to beable to detect multiple game objects in a 1x1 grid, 1x2 grid, 2x2 grid, 2x3 grid and 3x3 grid. Using raycast i couldn't see how to achieve this since a raycast only returns the first object it hits but using BoxColliders I can, by instantiating extra BoxColiders in the required grid layout.Below is my raycast code, just in case it is possible to achieve this gird layout required with Raycast
void playerRaycast()
{
// See: https://docs.unity3d.com/ScriptReference/Physics2D.Raycast.html & https://answers.unity.com/questions/1499447/how-to-distinguish-which-layer-has-been-hit-by-ray.html
requiredLayersMask = layermask1 | layermask2 | layermask3; //Logic copied from here: https://answers.unity.com/questions/1499447/how-to-distinguish-which-layer-has-been-hit-by-ray.html
//int layerMask = LayerMask.GetMask("Plot"); // Use whatever mask you assigned to your ground tiles (plots) (Not used, but could be useful code)
float distance = 1.0f; //Changes this to make the raycast go further?
Vector2 direction = this.playerDirection == PlayerDirection.Left ? Vector2.left :
this.playerDirection == PlayerDirection.Right ? Vector2.right :
this.playerDirection == PlayerDirection.Up ? Vector2.up : Vector2.down;
RaycastHit2D hit = Physics2D.Raycast(transform.position, direction, distance, requiredLayersMask);
Debug.Log("Player is facing: " + playerDirection);
Debug.DrawRay(transform.position, direction, Color.red, 10, false);
Debug.Log("Raycast: " + hit.transform);
//If the raycast collider hits another collider, Do something such as farm work or talk to a NPC
if (hit.collider != null)
{
if (hit.collider.gameObject.layer == LayerMask.NameToLayer("BigResource"))
{
Debug.Log("Hit a Big Resource");
if(hit.collider.tag == "rock")
{
hit.transform.gameObject.GetComponent<BigRockScript>().DamageObject(hit);
}
else if(hit.collider.tag == "log")
{
hit.transform.gameObject.GetComponent<BigLogScript>().DamageObject(hit);
}
}
else if (hit.collider.gameObject.layer == LayerMask.NameToLayer("SmallResource"))
{
Debug.Log("Hit a Small Resource");
if (hit.collider.tag == "rock")
{
hit.transform.gameObject.GetComponent<SmallRockScript>().DamageObject(hit);
}
else if (hit.collider.tag == "log")
{
hit.transform.gameObject.GetComponent<SmallLogScript>().DamageObject(hit);
}
}
else if (hit.collider.gameObject.layer == LayerMask.NameToLayer("Plot"))
{
cropManagerController = hit.transform.gameObject.GetComponent<CropManagerController>(); //This completes the reference to the CropManagerController when the raycast hits a gameObject that is CropManagerController
cropManagerController.DoFarmWork(hit); //Depending on the state of the plot, this could be watering, planting a seed, cleaning rubbish etc }
}
}
}
Answer by Seb_GTB · Feb 12, 2021 at 09:14 AM
ok... first of all never use "else if" they very slow and sometimes they are not detected. So you can try change all the "else if" to "if".
Also, the layers are very irritating because there are two list of layer that might cause troubles... one are the serialized fields or public layer mask variables that you made and the other one is the list where you choose the layer of each object, if you are a beginner I recommend you to use Tags.
But if I were in your situation... You could adapt this to what ever you want.
void OnCollisionEnter2D(Collision2D collision)
{
Debug.Log($"Hit a {LayerMask.LayerToName(collision.gameObject.layer)}");
}
Hope I'm right and you like it.
or just add "return" . .
void OnTriggerEnter2D(Collider2D collision)
{
if (collision.CompareTag("Player"))
{
if (collision.gameObject.layer == Layer$$anonymous$$ask.NameToLayer("BigResource"))
{
Debug.Log("Hit a Big Resource");
return;
}
if (collision.gameObject.layer == Layer$$anonymous$$ask.NameToLayer("SmallResource"))
{
Debug.Log("Hit a Small Resource");
return;
}
if (collision.gameObject.layer == Layer$$anonymous$$ask.NameToLayer("Plot"))
{
Debug.Log("Hit a plot");
return;
}
}
}
Your answer
Follow this Question
Related Questions
Raycast layer mask problem 1 Answer
Is it possible to allow a raycast to pass through a collider to hit things behind it? 6 Answers
A question about "Physics.Raycast()" 1 Answer
Why is Physics.Raycast returning colliders in a layer not included in the layermask? 2 Answers
IsTouchingLayers Not Returning True Despite That It Should 0 Answers