I guess you should read the manual, how Unity Tilemap is structured. If you create a Tilemap in Unity Editor, first you have a Grid and then a Tilemap under it. If you move Grid, Tilemap will move along it. This same thing is true for getting tiles in code. Tiles are stored in GridLayout space not in world space. So if you happen to start "drawing" you tiles from Scene world position 0,0,0 that doesn't mean Grid origin couldn't be in other location (like -2,-2,0 for example).
So one solution is to first convert screen mouse position to ray, then Raycast with this Ray against a plane matching Tilemap plane, then convert the world hit point to Grid space cell position and try to get a Tile.
It has been quite a while since I touched Tilemap and I'm no professional coder by any means, but this is one way to get your tiles under mouse cursor. I guess there might be more cleaner and shorter ways to do this...
if (Input.GetMouseButtonDown(0))
{
// mouse position in screen space
var mpos = Input.mousePosition;
// Create a ray from camera to world
var ray = Camera.main.ScreenPointToRay(mpos);
// Create a Plane object to raycast against
// Assume Tilemap resides on plane z 0
var plane = new Plane(Vector3.back, Vector3.zero);
// Do a Plane Raycast with your screen to world ray
float hitDist;
plane.Raycast(ray, out hitDist);
// If you aimed towards this infinite Plane, it hit
var point = ray.GetPoint(hitDist);
Debug.Log("Point: " + point);
// Convert hitpoint to Tilemap / GridLayout space
// Cell position is an integer positions in GridLayout
var tpos = tilemap.WorldToCell(point);
// Try to get a tile from cell position
var tile = tilemap.GetTile(tpos);
if (tile != null)
{
// A tile exists in this cell
Debug.Log("Tile sprite: " + tilemap.GetSprite(tpos));
}
}
See also:
https://docs.unity3d.com/ScriptReference/Tilemaps.Tilemap.html
https://docs.unity3d.com/ScriptReference/GridLayout.html
https://docs.unity3d.com/ScriptReference/Plane.html