Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

Question Detecting existing colliders in 2D

Discussion in '2D' started by SeriousWays, Feb 13, 2021.

  1. SeriousWays

    SeriousWays

    Joined:
    Mar 19, 2019
    Posts:
    4
    Hello!
    I am kind of new at Unity, so I hope my question will seem simple and easy to solve.

    I am playing around with the engine. Currently I have a small field and a UI with one button for spawning a prefab. When I click the button it spawns the prefab on top of the mouse and then after a left click it places it in the world.

    I add a 2D box collider to the prefab, but when I use OnMouseEnter to check for collisions, it does not register at all.

    This is the code for the button which spawns the prefab.

    Code (CSharp):
    1. public class SpawnBuilding : MonoBehaviour
    2. {
    3.  
    4.     //Mudhut and coordinates for it
    5.     public GameObject mudHut;
    6.     public Vector3 coordinates;
    7.  
    8.     void Start()
    9.     {
    10.  
    11.     }
    12.  
    13.     // Update is called once per frame
    14.     void Update()
    15.     {
    16.  
    17. }
    18.  
    19.     public void Build() {
    20.  
    21.         coordinates = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 7);
    22.         Instantiate(mudHut, coordinates, Quaternion.identity);
    23.     }
    24.  
    25. }
    26.  

    This is the code attached to the prefab which allows to move and place it.

    Code (CSharp):
    1. public class PlaceBuilding : MonoBehaviour
    2. {
    3.     //Used for mouse coordinates
    4.     float x;
    5.     float y;
    6.  
    7.     //Used to detect collision with another building
    8.     private bool noCollision;
    9.  
    10.     // Start is called before the first frame update
    11.     void Start()
    12.     {
    13.         noCollision = true;
    14.     }
    15.  
    16.     // Update is called once per frame
    17.     void Update()
    18.     {
    19.  
    20.         x = Input.mousePosition.x;
    21.         y = Input.mousePosition.y;
    22.  
    23.         transform.position = Camera.main.ScreenToWorldPoint(new Vector3(x, y, 7));
    24.        
    25.         //Left click to place the prefab
    26.         if (Input.GetMouseButtonDown(0) && noCollision)
    27.         {
    28.             Cursor.visible = true;
    29.             gameObject.AddComponent<BoxCollider2D>();
    30.             Destroy(this);
    31.         }
    32.         //Right click to destroy the prefab
    33.         else if (Input.GetMouseButtonDown(1))
    34.         {
    35.             Cursor.visible = true;
    36.             Destroy(gameObject);
    37.             Destroy(this);
    38.         }
    39.     }
    40.    
    41.     //Enter collider
    42.     private void OnMouseEnter()
    43.     {
    44.         noCollision = false;
    45.     }
    46.  
    47.     //Exit collider
    48.     private void OnMouseExit()
    49.     {
    50.         noCollision = true;
    51.     }
    52. }
    53.  
    This method of doing it I saw in a book called "Getting Started with Unity 5.x 2D Game Development". There you make a simple tower defense and the code works. But for some reason, it does not work for me here.
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,546
    To start, know that the mouse callbacks are UI not 2D features which is what this forum is for. The reason I mention this is because there's a dedicated UI forum here if you have any UI questions in the future.

    So you delete the "PlaceBuilding" component using "Destroy(this);" but you also expect the same script to work and run "OnMouseEnter" and "OnMouseExit" callbacks? When you right click you delete the GameObject it's on and even delete the component which will already be set to be deleted because you're deleting the GameObject it's on. Those callbacks won't run if you delete the script component they're in.

    I guess it raises the question that whilst you're new to Unity, do you follow what the code is trying to do? If not then maybe look at those commands in the Scripting API reference documentation to get a better idea of what it's doing.

    As a side note, if you're using 2D colliders then you can use OverlapPoint to check intersection of a point with colliders. This means you don't need to use the UI callbacks.
     
    Last edited: Feb 13, 2021
  3. SeriousWays

    SeriousWays

    Joined:
    Mar 19, 2019
    Posts:
    4
    The problem has been fixed by using Rays to detect the presence of a collider on the screen, instead of relying on OnMouseEnter() to detect a collision.
     
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,546
    It's 2D, using rays makes no sense and often it's incorrectly used as a ray with zero length which is a point! That's used for 3D so it's often recommended for 2D.

    The equivalent in 2D is OverlapPoint as there's no depth (Z) in 2D. It's also super fast.