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 Setting new tile on tile map with collision?

Discussion in '2D' started by Bitmapstar, Jan 17, 2021.

  1. Bitmapstar

    Bitmapstar

    Joined:
    Jan 17, 2021
    Posts:
    5
    I'm working on a farming style game and I'm trying to set new tiles on the tile map when it is interacted with. To start I'm trying to set tiles to being highlighted when a collider is touching it. In my Player Movement script I have an empty game object that rotates around the player one tile away from where the player is facing that has a Collider2d and a Rigidbody2d attached to them. Then in a Tool Manager script attached to the rotating game object I have the code below.
    When I play the game however the tiles change rather arbitrarily around the point seemingly at random but almost never on the tile that the point is directly on top of. Any help would be much appreciated, I'm still really new to coding and I'm losing my mind over this.


    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.Tilemaps;
    public class ToolManager : MonoBehaviour
    {

    [SerializeField]
    private Tilemap soilMap;
    [SerializeField]
    private Tilemap grassMap;
    [SerializeField]
    private TileBase plowedSoil;
    [SerializeField]
    private TileBase highlight;
    [SerializeField]
    public Collider2D toolPoint;
    [SerializeField]
    public Collider2D soilCollider;
    private void Update()
    {
    if (toolPoint.IsTouching(soilCollider))
    {
    Transform toolTransform = this.transform;
    Vector3 toolPosition = toolTransform.position;
    Vector3Int toolPositionInt = new Vector3Int((int)toolPosition.x, (int)toolPosition.y, 0);
    Debug.Log(toolPositionInt);
    grassMap.SetTile(toolPositionInt, highlight);
    }
    }
    }
     
  2. Derekloffin

    Derekloffin

    Joined:
    Mar 14, 2018
    Posts:
    322
    I think you should use the grid conversion function to convert position info (in this case worldtocell, and if you need it in the future celltoworld). That could very well be the whole issue here, but not sure.

    As two asides that sorta related:
    You might actually want to have the tool position be controlled by the cursor instead of the player position, and have the player appropriately approach/face it. I use a similar method to yours to determine what I can pick up, but for managing stuff I found it was too clumsy for the player to aim at precise squares to do it similarly.
    Second, if you do do it that way, you may want to do your highlight using a virtual tile instead of altering the tilemap. A virtual tile is basically a gameobject that you have overlay the tilemap at exactly the right coordinates so that it obscures the tile behind it, effectively replacing it visual without actually changing the tilemap itself. This way if the you have a sort of ghost system where the player can preview what they're about to do, you don't have to worry about replacing the previous tile if they abort as the tilemap hasn't change. You just instead change your fake tile all the time. And for a highlight, you don't even need a proper tile, just an appropriate tile with some alpha to be transparent to give the tile a different shade or the like.
     
  3. Bitmapstar

    Bitmapstar

    Joined:
    Jan 17, 2021
    Posts:
    5
    Thanks for the reply, any idea how I would implement that worldtocell conversion in this code?
    as far as the asides go the reason I'm using this method is because I'm building the game to be controller based rather than mouse and keyboard. an as for the virtual tiles, I had no idea this was a thing! I will definitely have to look into that.
     
  4. Derekloffin

    Derekloffin

    Joined:
    Mar 14, 2018
    Posts:
    322
    First you need a reference to the grid, so add a new public variable of type grid, then in the editor drag your tilemap grid to such to assign it.
    Then replace the line Vector3Int toolPositionInt = new Vector3Int((int)toolPosition.x, (int)toolPosition.y, 0);
    with
    Vector3Int toolPositionInt = grid.worldtocell(toolposition);
    assuming you name your grid variable grid (replace that name if not to whatever variable name you're using instead).

    And yeah, I found virtual tiles quite handy. Once you figure out the proper positioning to match that of the tilemap, they are really flexible, and avoid things like the tilemap having to recompute its colliders all the time for things that are temporary.
     
    Bitmapstar likes this.
  5. Bitmapstar

    Bitmapstar

    Joined:
    Jan 17, 2021
    Posts:
    5
    That totally worked! I thank you and my sanity tanks you so much!