Search Unity

Mouse Position to Tile Coordinates. Negative Coordinates?

Discussion in 'Scripting' started by gogocook25, Mar 14, 2019.

  1. gogocook25

    gogocook25

    Joined:
    Sep 30, 2018
    Posts:
    36
    Hi, I've been banging my head about this for a while now. Simply, I want to convert a mouse position to the tile position. In the code below, I convert Screen > World > Cell. Unfortunately, this gives me some negative values for the y coordinate, which is not compatible with my 2d tilemap which I want to have a 0,0 origin.

    Code (CSharp):
    1.         Vector3 worldCoord = Camera.main.ScreenToWorldPoint(touchPos);
    2.         Vector3Int cell = grid.WorldToCell(worldCoord);
    3.         Vector3 localCoord = grid.WorldToLocal(worldCoord);
    4.         Debug.Log("cell is " + cell + " and local coordinates are " + localCoord);

    My hierarchy looks like this (Grid is Child of Camera, TileMap Child of Grid)

    Main Camera
    ----Grid
    --------TileMap

    I set Grid's position to 0,0. I made it a child of Camera because I thought doing so would put it on the same world coordinate system in case that was messing up the conversion to tile coordinates. Please help. I am at my wits end.
     
  2. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    Hi @gogocook25

    Are you using orthographic camera or Perspective camera? So you actually get the tile coordinates?

    "Unfortunately, this gives me some negative values for the y coordinate, which is not compatible with my 2d tilemap which I want to have a 0,0 origin."

    Perspective camera won't give you right coordinates with screen to world point.

    AFAIK grid coordinates can go to negative coordinates. So something like this should give you proper tile positions:

    Code (CSharp):
    1. worldPos = Camera.main.ScreenToWorldPoint(mousePos);
    2. tilePos = tileGrid.WorldToCell(worldPos);
    There is nothing preventing you from painting / placing tiles in 3d space, so you'll have area of tiles, use the tilemap bounds to see where your tiles are placed.

    Also, you can just place your grid to 0,0,0 like you said and start adding tiles from 0,0,0 up and right so you never use negative coordinates if that somehow is a problem. If you actually did so, you can erase tiles in negative coordinates and do a compress bounds from tilemap's inspector menu.
     
    gogocook25 likes this.
  3. gogocook25

    gogocook25

    Joined:
    Sep 30, 2018
    Posts:
    36
    I'm using orthographic camera. I do set the transform position of the grid and camera at 0,0,0 but debug logging the world coordinates when I click inside the camera shows 0,0,0 outside of the camera boundaries. What does setting transform position do in relation to world position? Thanks.
     
  4. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    Placing the orthographic camera at the default (0, 0, -10) generally means that the center of the viewing screen will be (0, 0) world position. The "size" of the camera then describes the extents of the viewing screen, where the screen will range from (-size, size) in terms of height and (-size * widthFactor, size * widthFactor) in terms of width depending on the aspect of your screen (16:9, 4:3 ...).

    If you would like your Tilemap to start from (0, 0) at the bottom left of the screen, you will need to place your Camera at (size * widthFactor, size) relative to the TilemapGameObject. This ensures that (0, 0) is aligned with the bottom left from the Camera's view.

    Also, take note of the following:
    https://docs.unity3d.com/ScriptReference/Camera.ScreenToWorldPoint.html
    Code (CSharp):
    1.        
    2.         // Get the mouse position from Event.
    3.         // Note that the y position from Event is inverted.
    4.         mousePos.x = currentEvent.mousePosition.x;
    5.         mousePos.y = cam.pixelHeight - currentEvent.mousePosition.y;
    6.  
    Screen coordinates go from the bottom left, so (0, 0) represents the bottom of the screen. Event.mousePosition goes from the top left, so (0, 0) represents the top of the screen. Input.mousePosition starts from bottom left, so no conversion should be required.
     
    gogocook25 likes this.