Place & Destroy Tiles in Tilemap Problem

Hi, I have a script that places and destroys tiles in a tilemap with the left and right mouse button. My problem is, is that it will only work sometimes when I click a tile. I can keep clicking the tile and nothing will happen many times and all of a sudden it will work randomly.

Here is the code - help would be much appreciated.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;

public class PlaceAndDestroy : MonoBehaviour
{
    public RuleTile grassTile;
    public Tilemap groundTilemap;

    public float castDistance = 1.0f;
    public LayerMask layer;

    float blockDestroyTime = 0f;

    Vector3 direction;
    RaycastHit2D hit;

    bool destroyingBlock = false;
    bool placingBlock = false;

    private void FixedUpdate()
    {
        GetMousePos();
    }

    void GetMousePos()
    {
        hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), direction, castDistance, layer.value);
        Vector2 endpos = Camera.main.ScreenToWorldPoint(Input.mousePosition) + direction;

        if (Input.GetMouseButtonDown(0))
        {
            if (hit.collider && !destroyingBlock)
            {
                destroyingBlock = true;
                StartCoroutine(DestroyBlock(hit.collider.gameObject.GetComponent<Tilemap>(), endpos));
            }
        }

        if (Input.GetMouseButtonDown(1))
        {
            if (!hit.collider && !placingBlock)
            {
                placingBlock = true;
                StartCoroutine(PlaceBlock(groundTilemap, endpos));
            }
        }
    }
    IEnumerator DestroyBlock(Tilemap map, Vector2 pos)
    {
        yield return new WaitForSeconds(blockDestroyTime);

        pos.y = Mathf.Floor(pos.y);
        pos.x = Mathf.Floor(pos.x);

        map.SetTile(new Vector3Int((int)pos.x, (int)pos.y, 0), null);

        destroyingBlock = false;
    }

    IEnumerator PlaceBlock(Tilemap map, Vector2 pos)
    {
        yield return new WaitForSeconds(0f);

        pos.y = Mathf.Floor(pos.y);
        pos.x = Mathf.Floor(pos.x);

        map.SetTile(new Vector3Int((int)pos.x, (int)pos.y, 0), grassTile);

        placingBlock = false;
    }
}

Bump

Why are you using a raycast for 2D for mouse selection using a direction of Vector3 zero (this is 2D not 3D) and a distance of 1? Are you not trying to check what is under the mouse point?

If so then try to not use some degenerate raycast that looks like it was copied from some 3D script and use OverlapPoint instead. If you were not aware of this then I would highly recommend looking at the queries available in the API reference here.

You can also do “if (hit)” rather than the more verbose “if (!hit.collider)” etc.

As to why you’re having problems I’m not sure but maybe that bad raycast is the source of your issues.