Want a highlighted cell to follow the mouse, then be placed on the tile map

Godot Version

4.4.stable

Question

I’m trying to make a “Building Planner” mode where once the player clicks on the “Build” button, the screen becomes an opaque white and a blue square follows the cursor. I make a simple tile map that has both the opaque white tile and the blue highlight tile. Making the screen an opaque white worked fine, but I am having trouble getting the highlighted cell to be placed. When I click on the screen, the cell does not become highlighted. Below is the code I have so far:

extends TileMapLayer

var width : int = 150
var height : int = 300

var plan_status : bool = false

func _on_build_pressed():
  if plan_status == false:
    for x in range(-width/2, width/2):
      for y in range(-height/2, height/2):
        set_cell(Vector2i(x,y), 2, Vector2i(0, 0))
    plan_status = true
  elif plan_status == true:
    for x in range(-width/2, width/2):
      for y in range(-height/2, height/2):
        set_cell(Vector2i(x,y), -1)
    plan_status = false

if Input.is_action_just_pressed("click"):
  var mouse_pos = get_global_mouse_position()
  var local_tile_mouse_pos = local_to_map(mouse_pos)
  set_cell(local_tile_mouse_pos,2,Vector2i(0,1))

If you throw a print(local_tile_mouse_pos) in your click code, do you get what looks like a reasonable value?

Does your tileset actually have the highlight tile? A couple of times I’ve been bitten by this, where I’ve added a new tile to the source image, but forgot to tell Godot to add that tile to the set.

I tried that, but no coordinates gets printed. And yes, I do have the highlight tile in my TileMap

It looks like this function is only called when you press the build button instead of whenever you move the mouse. Try using _input or _unhandled_input

That’s the intention. The intention is when the player presses the “build” button, the highlighted tile then pops up and follows the mouse to help the player plan where to build buildings.

I just found the problem. I removed the following line of code:
“if Input.is_action_just_pressed(“click”):”
After removing this line, I reduced the indentation of the three lines of code afterwards, to take it out of the if statement.

Now the tile does change the way I intended, but only on the tile when I click on the “build” button. It doesn’t follow the mouse or anything. So my code is flawed and more brainstorming is needed. Nevertheless, I appreciate the help everyone!

In case anyone is curious, this is the code that worked:

@onready var highlighted_marker: Sprite2D = $Highlighted_marker

func _process(delta: float):
	var mouse_pos = get_local_mouse_position()
	var cell_pos = local_to_map(mouse_pos)
	highlight_cell(cell_pos)

func highlight_cell(cell_position: Vector2i):
	highlighted_marker.position = map_to_local(cell_position)

But now, I’ve run into another problem. I want the above functions to be active only when the “Build” button is pressed. Then made inactive when the Build button is pressed again. When I put the functions under the func _on_build_pressed(): code, I get the “standalone lambdas cannot be accessed error.” How do I fix this?

Use the set_process() function

Tried that but it didn’t work. I did some tinkering and what DID work was the following:

func _process(_delta: float):
	if plan_status == true:
		var mouse_pos = get_local_mouse_position()
		var cell_pos = local_to_map(mouse_pos)
		highlight_cell(cell_pos)

func highlight_cell(cell_position: Vector2i):
	highlighted_marker.position = map_to_local(cell_position)

“plan_status” is a variable that changes from “false” to “true” when I press the button. However, a new problem came up: the highlighted cell stays at a tile during regular gameplay when it shouldn’t be there. The video below shows my issue:

Hide the marker when you exit the build mode.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.