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. Dismiss Notice

Question creating UI Panels on top of tilemap cells

Discussion in '2D' started by korog, Sep 15, 2020.

  1. korog

    korog

    Joined:
    Jun 10, 2015
    Posts:
    1
    I am trying to create Ui.panels (that might have one or several small buttons) on top of some tilemap cells.

    I need to find out what coordinates I should use for creating them on my canvas.

    This person had very similar problem https://forum.unity.com/threads/adding-a-button-to-specific-tiles-in-a-tilemap.856393/ and what I gathered from the response is that my problem might not have a solution at all..


    Also, if I did realize, while I will be scrolling my tilemap, the panels need to be updated as well so they keep their positions on top of those cells.
     
  2. eses

    eses

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

    What kind of canvas type were you thinking about? That also makes a difference.

    Anyway, you'll have to convert either the tile world position or the screen position into Canvas / RectTransform position and then use that value to place your RectTransform.
     
    Last edited: Sep 15, 2020
  3. Lo-renzo

    Lo-renzo

    Joined:
    Apr 8, 2018
    Posts:
    1,315
    I wrote the response in the linked thread.
    Not so! You just need to convert coordinates a couple times.
    Code (CSharp):
    1. var pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    2. Vector3Int cell= tilemap.WorldToCell(new Vector3(pos.x, pos.y));
    3. TileBase tile = tilemap.GetTile(cell);
    If this is how we get the cell the mouse is hovering over, we just need to do the reverse.
    Code (CSharp):
    1. Vector3 worldPos = grid.CellToWorld(cell); // go from cell-space to world-space
    2. var screenPoint = Camera.main.WorldToScreenPoint(worldPos); // go from world-space to screen-space
    Because the Canvas uses screen-space, we're almost done. Now we have the pixel coordinate we could place our button.
    Code (CSharp):
    1. RectTransform tr = (myButton.transform as RectTransform);
    2. tr.position = screenPoint;
    Let's say you want to monitor the click of the mouse. If they clicked on an interactable item on the tilemap, you want to instantiate some UI stuff to allow the player to adjust something. That's totally possible with the above code. You'd just need to grab from the tile whatever information your UI needs to create to create buttons / sliders / whatever. The tile, however, would need to be some special derived class of your making, e.g. ClickableTile or the like, that you can cast to, allowing you to access its fields which store the UI info.

    Note - you may want to adjust this to use anchorPosition instead. Be mindful of the the rich RectTransform options. https://docs.unity3d.com/2017.1/Documentation/Manual/class-RectTransform.html

    Yes, that would be necessary. Another way to do this would be to not use Unity UI and instead use GameObjects / SpriteRenderers / Collider2D in their place by instantiating in world space. You lose the Unity UI features, like Canvas Scaling, in exchange for your buttons existing in the world, which might be a trade off that's worth it for your use case.
     
    Last edited: Sep 15, 2020