Help With Updating "Map" Screen

Godot Version

3.5.stable


This week I am getting into some more complex UI stuff.


Question 1

So I’m trying to make a resizable and movable UI window that can scroll. I know there are nodes for a resizable window and a scroll window, but I need them to be both one in the same.

Can I use one as a parent of the other or will I need to code for part of this? E.g. Use the scroll window, but code the resizable/movable part.


Question 2

This question may be a bit more… complex (to me, anyways).

In these UI windows, I want to have points of interests (which are my scenes) for each zone the player is in.

I have one camera for each “class” the player can choose in which the UI window will be in. I have my zones structured as trees. E.g. zone 1 has 5 poi, zone 2 has 7 poi, zone 3 has 4 poi, etc.

I have no idea how to update this UI window to show what is in the current zone. How would I go about doing this?


What are your thoughts/ideas? Do you have any resources for these types of things? Please help, lol.

Thank you, all!

Update!


I have decided that I will not make the ui movable or resizable, but make it a static screen that will open with a key press/button press. This will make it more accessible for controller support.


Still kind of stuck on this one. With the current knowledge that I have, I figured that I could make a separate “map” screen for each zone and each poi (scene) could have a function that calls for which “map” screen to appear. This just seems like a lot of, potentially, unnecessary work.

Is this a good route to take? Or is there a better way to go about this?

I can’t quite picture this. Can you post a sketch of how this would look and function?

1 Like

Yeah!

Here is how my zones are structured in godot:

Screenshot 2024-06-04 004522

And how my classes are structured:

Screenshot 2024-06-04 004721


These gui examples are pretty rough as I made them in 2.5 seconds, but…

Here is an example of a graphic ui:

I would have a cursor that you can move around. Selecting a main poi (such as a planet or star) would transport you to it or bring up a sub-menu of the things around it (such as a moon or station).

If the sub-menu for the smaller poi becomes too much of a hassle, I would probably just add markers for the moons.

And this would update for each zone/system.


Text UI Example

I’m not sure if I like this approach as much. I probably won’t use this unless it is easier to implement:


Apologies again for the rough examples. It’s late for me and I need to head to sleep, lol.

Let me know if I can clarify further!

1 Like

Is there a way to check what branch I am currently in? Something like:

func get_map():
get_tree()
   if player.is_in(test_system_1) && input.action_is_just_pressed("Map"):
   map.open("test_system_1_map.tscn")

   elif player.is_in(test_system_2) && input.action_is_just_pressed("Map"):
   map.open("test_system_2_map.tscn")

I know this code is not real, but is there something similar to this that would work?
Also, if I had a bunch of systems (say 100 or so) would this code be… okay?

The space ui

The text ui would definitely be simpler, but space ui is always better!

Here’s some example code:

func create_system(data):
	var center := position + size / 2.0
	for orbit_i in data.orbits.size():
		var orbit = data.orbits[orbit_i]
		var orbit_visual = load("res://the_orbit_visual.tscn").instantiate()
		add_child(orbit_visual)
		orbit_visual.size = Vector2(orbit.radius, orbit.radius) * 2.0
		orbit_visual.position = center - orbit_visual.size / 2.0
		
		for planet in orbit.planets:
			var planet_visual = load("res://the_planet_visual.tscn").instantiate()
			add_child(planet_visual)
			var radius = Vector2(orbit.radius, 0.0)
			var point = radius.rotated(randf() * 2 * PI)
			planet_visual.name = planet.name
			planet_visual.size = planet.size
			planet_visual.position = center + point - planet.size / 2.0
			planet_visual.setup_sub_visuals(planet)
			planet_visual.gui_input.connect(_on_planet_input.bind(planet))
			planet_visual.focus_entered.connect(_on_planet_focused.bind(planet))
			planet_visual.focus_exited.connect(_on_planet_unfocused.bind(planet))

func _on_planet_input(event: InputEvent, planet_data):
	if event is InputEventMouseButton and event.pressed:
		load_planet_scene(planet_data.scene)

The above assumes the orbit and planet visuals and the script node all inherit from Control. Use the controls gui input signal with the planet data bound to dynamically load the corresponding planet scene.

The load planet scene may handle setting what system, planet, whatever you are entering. Probably in a autoload.

The architecture

Overall, the most important idea is to decouple your data from scenes to reduce the amount of repetition.

Yes, this would be a lot of work. Instead of creating a scene for each map, create a base scene that uses some given data, preferably as a custom resource, to generate the map.

This would depend on how your game is designed. For example, if these systems are in an open world, you could use an Area2D that covers the system and the Area2D holds the identifying data about the system.

If each system/planet/star is its own scene that you load your player into – discarding the previous scene – then the most straightforward way is to store the system identifying data in an autoload.


I haven’t edited the above to read better and didn’t explain the code. Hope this helps some, anyway. I’ll come back later and edit it.

1 Like

One more thing, if you see code like this where it repeats and usually there is only a little bit that changes per block, there is a better way.

For example:

# Index
var system_index = 1
map.open(str("system_", system_index, "_map.tscn"))

# Dictionary
var the_systems = {"SystemName": system_data, ...}
map.open(the_systems[get_current_system_name()].scene)

# Autoload
map.open(GameManager.current_system.scene)
1 Like

Not going to lie, a lot of this went way over my head :sweat_smile: But I knew the interactable GUI stuff would be the most difficult for me.

I will mess around with this and see if I can gain some understanding of it! And thank you!

Will update later with my findings~

1 Like

I have come to the conclusion that I do not have the knowledge to draw/place things from code at this point in time. I will have to experiment with this later.

So, I think I will draw the maps manually for each zone (system) and use button nodes with custom textures to move between poi (scenes). This will be more work, but I am fine with this as I am primarily a visual artist and am pretty bad at coding, haha. :smiling_face_with_tear:

I guess I don’t understand this either.

The only thing that comes to mind when I see this is to have a script for each poi (scene) that gives it an ID, then having an autoload that checks each poi (scene) for the ID, then loading the appropriate map based on that ID.

I think I would need a tutorial to and mess around with to really understand how to implement this stuff.

Thank you again for helping me! I appreciate it~