Hello all.

I've been trying to put together a very small isometric scene inspired from old-school RPGS for the past 2 weeks.
So far, I've been able to implement a very basic A* pathfinding and a circle around the player that serves as a field of view for the player.
However, I'd like to have a field of view that could be blocked by walls and obstacles, where only the "clear" tiles could be seen, a bit like this :

I could find two implementations of that in Gdscript.
The first one : [https://github.com/Zireael07/Veins-of-the-Earth-Godot/blob/master/FOV_gen.gd] asks for a 2d array of int as source for the calculations.

I could find some resources about creating a 2d array, but is there a way to create one and automatically feed it all the values inside get_used_cells() ?

The second script : [https://github.com/matt-kimball/godot-mrpas] has simpler functions, but they all ask for Vector2 variables to function properly.

Here is a function of the script, that asks for a Vector for a position.

func set_transparent(position : Vector2, transparent: bool) -> void:
if _in_bounds(position):
_transparent_cells[position.y][position.x] = transparent

And I get almost the same problem with get_used_cells with effectively contains Vector2 for each of the tiles but is an array. I tried creating a small function that iterates through it and returns every value, but it doesn't work.

TLDR :
1) Is there a way to create a 2d array with all the values inside get_used_cells() that wouldn't require one hour of manual input?
2)How to properly give a function a Vector2 variable contained inside get_used_cells(), instead of the actual array?

Sorry for the lenghty post.

I may be missing some subtle point, but try this:

extends Node2D


var tm:TileMap


func _ready() -> void:
	tm = get_node('TileMap')

	# Make a 2d array.
	var arr2 := []
	var r = tm.get_used_rect()
	for x in r.end.x + 1:
		arr2.append([])
		for y in r.end.y + 1:
			arr2[x].append(tm.get_cell(x, y))

	# Pass a vector to a function.
	for v in tm.get_used_cells():
		a_func(v)


func a_func(v:Vector2):
	pass

I have some similar fog-of-war-type functions in my dgen project, but you'd have to wade through a lot of code to find them, and they probably work the same way -- check each tile for transparency along a line, then mark everything past the first blockage as dark.

    duane
    Thank you for your helpful answer!
    It helped me understand how to structure better all of this.

    However, I still haven't been able to use the Vector2 function properly, since the first function of the FOV script mrpas.set_transparent(returnOcc(), false return a conversion error : Unable to convert from Nil to Vector2.

    Your functions seem to work as expected (I can see the functions returning Vector2 points with breakpoints), but as soon as it enters the "main" function for the FOV, it returns the conversion issue.

    Here are the declared variables and the functions:

    Here is the main FOV function I call from another script (with the function returning the error at 38):

    I've noticed that the returnOcc() function (where it iterates through my tilemap and return a Vector2) seems to loop through all the tiles BEFORE actually passing the Vector2 nodes to the main function.

    If I'm correct, maybe putting a yield() inside the returnOcc() (that would call the main function) could stop the loop and pass the variable before looping back again?

    I wouldn't try to use an onready variable to call get_used_cells(), since even if all the child objects in your project are ready now, you might change something later that would throw them out of whack. Try calling get_used_cells() right before you use it. I never do anything in an onready other than getting nodes (and sometimes I put that in another method). If that doesn't work, then yielding until the next frame from _ready() might fix it. The safest way to do initialization functions is from a timer or a loading screen -- that way you know everything in your scenes has loaded.

      duane

      Thank you, it works now.
      I've deleted the onready vars and called them when needed inside the functions. And it turns out I only needed to call the function inside the loop and pass it the iteration variable "v", like so :

      Simple stuff, but I think I have trouble simplifying my thoughts and always end up overcomplicating stuff, haha.

      Anyway, thank you for the help and for the code snippets, they'll definitely prove useful again later on during this project!