Search Unity

Bug Camera.main.ScreenToWorldPoint(Input.mousePosition) not working?

Discussion in 'Scripting' started by VeryGoodDeveloperISwear, Apr 1, 2023.

  1. VeryGoodDeveloperISwear

    VeryGoodDeveloperISwear

    Joined:
    Jan 7, 2023
    Posts:
    56
    I am trying to detect the position of the mouse and create a ray. If it detects a gameobject that has the "Tile" tag and that same gameobject has been clicked twice, it will delete it. However, I've noticed that the mousePos variable is always the same, and also that it is the exact same as my camera's transform

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class TileClick : MonoBehaviour
    4. {
    5.     private Vector3 mousePos;
    6.     private RaycastHit2D hit;
    7.     private GameObject prevTile;
    8.     private GameObject tile;
    9.  
    10.     private void Update()
    11.     {
    12.         if (Input.GetButtonDown("Fire1"))
    13.         {
    14.             Debug.Log("mouse clicked down");
    15.             mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    16.             TileClicked();
    17.             prevTile = tile;
    18.         }
    19.     }
    20.  
    21.     private void TileClicked()
    22.     {
    23.         hit = Physics2D.Raycast(mousePos, Vector2.zero);
    24.         Debug.Log(mousePos);
    25.         if (hit.collider != null)
    26.         {
    27.             Debug.Log(hit.collider.gameObject.name + " has been hit");
    28.             if (hit.collider.gameObject.tag == "Tile")
    29.             {
    30.                 tile = hit.collider.gameObject;
    31.             }
    32.         }
    33.  
    34.         if (prevTile!=null)
    35.         {
    36.             if (prevTile == tile)
    37.             {
    38.                 Destroy(tile);
    39.             }
    40.         }
    41.     }
    42. }
    I've tried changing Camera.main to a serializable camera variable, but it still does not fix this issue. My camera also has the "MainCamera" tag
     
  2. VeryGoodDeveloperISwear

    VeryGoodDeveloperISwear

    Joined:
    Jan 7, 2023
    Posts:
    56
    I've fixed this using ChatGPT:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class TileClick : MonoBehaviour
    4. {
    5.     private Vector3 screenPos;
    6.     private Vector3 worldPos;
    7.     private RaycastHit2D hit;
    8.     private GameObject prevTile;
    9.     private GameObject tile;
    10.  
    11.     private void Update()
    12.     {
    13.         if (Input.GetButtonDown("Fire1"))
    14.         {
    15.             screenPos = Input.mousePosition;
    16.             screenPos.z = -Camera.main.transform.position.z;
    17.             Debug.Log("mouse clicked down");
    18.             worldPos = Camera.main.ScreenToWorldPoint(screenPos);
    19.             TileClicked();
    20.             prevTile = tile;
    21.         }
    22.     }
    23.  
    24.     private void TileClicked()
    25.     {
    26.         hit = Physics2D.Raycast(worldPos, Vector2.zero);
    27.         Debug.Log(screenPos);
    28.         if (hit.collider != null)
    29.         {
    30.             Debug.Log(hit.collider.gameObject.name + " has been hit");
    31.             if (hit.collider.gameObject.tag == "Tile")
    32.             {
    33.                 tile = hit.collider.gameObject;
    34.             }
    35.         }
    36.  
    37.         if (prevTile!=null)
    38.         {
    39.             if (prevTile == tile)
    40.             {
    41.                 Destroy(tile);
    42.             }
    43.         }
    44.     }
    45. }
    I'm still not sure why this change fixes the script, so any explanation would be helpful
     
  3. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    4,000
    That's a complete non-sensical fix. You should read the documentation of ScreenToWorldPoint. The screenspace position's "z" value should indicate the desired distance from the camera. Using the worldspace z position of the camera relative to the world origin makes no sense at all. The further the camera is away from the world origin, the further away the projected point would be from your camera. When you use
    5f
    for the z value, the resulting point would be 5 units away from the camera.

    Keep in mind that a single screen point maps to infinitely many points in worldspace. A while line / ray. You have to tell it which distance you actually want.

    It's not quite clear what your setup is, what kind of camera you're using (perspective or orthographic) and what your goal is. Since you use Physics2D it seems to be a 2d game / environment. So you usually would have an orthographic camera. So the distance from the camera shouldn't matter at all. If you use a perspective camera, you need to pass in the desired depth / distance from the camera.

    Also using a 2d raycast with no direction doesn't make much sense. This sounds like you wanted to use Physics2D.OverlapPoint.
     
    Last edited: Apr 1, 2023
    angrypenguin, Ryiah and Kurt-Dekker like this.
  4. VeryGoodDeveloperISwear

    VeryGoodDeveloperISwear

    Joined:
    Jan 7, 2023
    Posts:
    56
    Ah, my camera was perspective, not orthographic. Also, thank you for informing me about Physics2D.OverlapPoint, I haven't heard of that
     
    alikystefanmartiniuk likes this.
  5. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,183
    I'm thinking that must be GPT-3.5. GPT-4 tends towards being much more aware of what the code is trying to do.

    The issue with your mousePos variable being the same as the camera's transform is because you are not accounting for the depth (z-axis) when converting from screen to world point. Your current code uses Camera.main.ScreenToWorldPoint(Input.mousePosition), which does not include the proper depth information.

    To fix this, you need to add a depth value when converting the mouse position to world coordinates:
    Code (csharp):
    1. mousePos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.nearClipPlane));
    However, since you are using Physics2D.Raycast, it is better to keep the z-value at zero. So, you should adjust the z-value of the mousePos variable before using it for raycasting:
    Code (csharp):
    1. mousePos = new Vector3(mousePos.x, mousePos.y, 0);

    Unfortunately this is one of those situations where the bot just isn't going to be helpful. You can get hints that the camera might not be set up correctly if you ask it if there is anything else that might be causing the problem but unless you get lucky with a hallucination (ie it's guessing) it's not going to mention orthographic vs perspective.
     
    Last edited: Apr 1, 2023