How do I create a tool hit location system like the one in Stardew Valley?

Godot Version

Godot v4.7.stable

Question

I’m trying to create a tool hit location indicator (that red square showing where you’ll hit with a tool).

I managed to write the code, but there’s a major issue with it.

The offsets for all sides (except the right side) are consistently shifting toward the right.

There’s also a problem with the tool interaction logic, but that’s in a different script, so I don’t think it’s related to this specific issue.three backticks or replace the code in the next block:

extends Sprite2D

var tile_size: int = 16 
var off_set: Vector2 = Vector2(0,0)
@onready var player: CharacterBody2D = $"../Objects/Player"
 # Adjust to your player's path

func _process(_delta: float) -> void:
	var player_pos: Vector2 = player.global_position
	var direction  = player.last_direction
		
	# Place the indicator 1 tile (tile_size) away from the player's center
	global_position = player_pos + direction  * tile_size
	
	# Snap to the global grid (assumes your tiles are square)
	global_position = global_position.snapped(Vector2(tile_size, tile_size))
	
	# Apply an offset to center the sprite within the tile if its origin is in the top-left
	global_position += Vector2(tile_size / 2, tile_size / 2)

You always add the direction to the player position so you always end up on the right I think.

Shouldn’t you also be snapping your player_pos variable to a tile? I think that may solve it.

You may also want to reconsider more of this logic.

If you’d simply place this node one tile away from the player in the direction the player is facing while the player’s rotation is zero, you won’t need to use the player’s global position at all, seeing as this node is already a child node of the player anyway it will rotate around with the player by default. This could reduce all your code to a single line in which you simply snap and center the position of this node to the tile it’s on.

Assigning the player var like this may also be kind of risky; what happens when you rearrange the nodes in your scene tree?

In the solution I propose you don’t even need a reference to the player anymore, achieving a more loosely coupled setup. The less code depends on other code, the better. You can test stuff in isolation this way, stuff doesn’t break other stuff as easily this way as well.

You could just apply a shader to the tile the player is facing.