Rookie
Rookie

Reputation: 193

Unity: Raycast Doesn't Work For The Child Object's Collider

I have a tile based game. I place towers as child objects of tiles. I want to be able to detect mouse clicks on towers but not tiles, with raycasting. Both tiles and the towers have 2d box colliders. I can detect clicks on tiles but raycast won't detect the ones on the towers. How can I solve this problem. Thanks.

Here is my code for raycasting:

if (Input.GetMouseButtonDown(0))
        {
            Ray ray = camera.ScreenPointToRay(Input.mousePosition);

            ray.origin = camera.transform.position;

            RaycastHit2D hit = Physics2D.Raycast(camera.transform.position, -Vector2.up, 50, 8);

            if (hit.collider != null && !EventSystem.current.IsPointerOverGameObject())
            {
                Debug.Log(hit.collider.transform.tag);
                //Transform objectHit = hit.transform;

            }
        }
    }

When I mask the tiles (here layer 8) I get nothing. It seems rays never hit the towers although towers (like tiles) also have a 2d box collider.

Upvotes: 0

Views: 6956

Answers (2)

Mr.Bigglesworth
Mr.Bigglesworth

Reputation: 959

After a little research it seems that all child colliders of an object are considered to belong to the parent. This is so that you can build up a more complex collider out of smaller ones and this situation is commonly needed. The exact collider can still be referenced using it's transform property, for example:

if (hit.collider.transform != null)
{
   //Execute code
}

This will refer to the childs collider specifically.

Upvotes: 1

Mr.Bigglesworth
Mr.Bigglesworth

Reputation: 959

Unity uses a layer system and you can filter out which layers raycasts are using. You can use this to hit specific colliders and avoid others like your tiles/ towers issue. The syntax (for 2d version) is:

RaycastHit2D Raycast(Vector2 origin, Vector2 direction, float distance
= Mathf.Infinity, int layerMask = DefaultRaycastLayers, float minDepth
= -Mathf.Infinity, float maxDepth = Mathf.Infinity);

Here you can see the layermask parameter choose a different layer to the one your parent object is on. Then place the children on a different layer using the drop down menu in the inspector as seen below.

enter image description here

You can set the layers of parents and child gameobjects separately.

Hope that helps

Upvotes: 1

Related Questions