Raptorkillz Jesusemora how would I make it work with inputs

what do you mean by inputs? like keys or do you mean the signals?

Raptorkillz kuligs2 How would the scene tree look like

put your buttons inside a Control, space them anyway you want, you can use a container if you find one that can place them diagonally like that. this Control can be inside anything, but be a child of the root of the scene, you move this up and down, left and right.
for the buttons, there's an option in inspector that let's you set a next and previous button for using the keys or joystick. with the mouse is more complicated.

for triggering these functions and going to options, comp, etc, you can either hide elements of the scene and show/instantiate others, or, the easier way is to put each menu in a different tab of a tab container, so when you "press" one of the buttons it changes tab.

Raptorkillz Okay but the img that I showed has a scroll container

you asked how to do this, then hurried and did it before having any idea how.
you'll have to remake everything, that's just how things are done. you can move some of the nodes and convert others, but it's best if you keep it simple.

I don't see why you would put it inside a scroll container, it's going to look bad when the scrollbars appear and break everything, also it only goes up and down vertically, but you need to go up and to the side, down and to the other side.

you should name your nodes before continuing, even if that takes a bit longer. also you are using CanvasLayers for holding stuff, you don't need to.
put everything in the UI inside a single Control and avoid mixing Controls and 2D nodes. the 2D elements should be inside a Control in their corner/scene and not loose everywhere.

    Raptorkillz in the inspector, Controls have these options:

    it will change focus to Top when pressing the up key and Bottom when pressing the down key. You can also set Mode. It's very well documented and explained in the tooltips.

      4 months later

      Jesusemora I asked chat gpt and it gave me working code but the only thing that isn't working is that it uses tweens and the tween isn't moving

      extends Control
      
      @export var save = load("res://Data/Stages/Menu/SaveMenu.tscn")
      @export var encore = load("res://Data/Stages/Menu/EncoreMenu.tscn")
      @export var time = preload("res://Data/Stages/TZ/TestZonetime.tscn")
      @export var options =preload("res://Data/Stages/Menu/OptionsMenus.tscn")
      @export var Extras = preload("res://Data/Stages/Menu/ExtrasMenu.tscn")
      #go back to title 
      @export var back = preload("res://Data/Stages/Title/Title.tscn")
      
      # Variables for button management
      var buttons: Array = []
      var selected_index: int = 0
      var tween: Tween  # Declare a Tween variable
      
      # Called when the node enters the scene tree for the first time.
      func _ready():
      	buttons.clear()  # Clear any existing values (good practice)
      	
      	# Create a Tween instance
      	tween = get_tree().create_tween()  # Create a new Tween instance
      
      	# Loop through all child nodes of the Control node
      	for i in range(get_child_count()):
      		var button = get_child(i)
      		
      		# Check if the child is a TextureButton
      		if button is TextureButton:
      			buttons.append(button)  # Add it to the buttons array
      			button.set_meta("index", buttons.size() - 1)  # Store the button index as metadata
      			
      			# Connect the pressed signal using a lambda to pass the button
      			button.pressed.connect(Callable(self, "_on_button_pressed").bind(button))
      
      	# Set the initial selection
      	update_button_selection()
      
      func _input(event):
      	# Handle input for navigation
      	if event.is_action_pressed("gm_up"):
      		move_selection(-1)
      		$"../../CanvasLayer/Sprite2D".frame =0
      		$"../../CanvasLayer/AnimationPlayer".play("tv")
      		$"../../SFX/MenuBleep".play()
      		
      	elif event.is_action_pressed("gm_down"):
      		move_selection(1)
      		$"../../CanvasLayer/Sprite2D".frame =0
      		$"../../CanvasLayer/AnimationPlayer".play("tv")
      		$"../../SFX/MenuBleep".play()
      
      	# Handle 'gm_action' for triggering the selected button
      	elif event.is_action_pressed("gm_action"):
      		if selected_index >= 0 and selected_index < buttons.size():
      			buttons[selected_index].emit_signal("pressed")  # Manually emit the pressed signal for the selected butbutbutt
      	elif event.is_action_pressed("gm_action2"):
      		Global.main.change_scene_to_file(back, "FadeOut")
      func move_selection(direction: int):
      	var prev_index = selected_index  # Store the previous index
      	selected_index += direction
      	
      	# Wrap around selection
      	if selected_index < 0:
      		selected_index = buttons.size() - 1  # Wrap to the last button
      	elif selected_index >= buttons.size():
      		selected_index = 0  # Wrap to the first button
      	
      	# Update button visuals and start tween animation
      	update_button_selection()
      	
      	# Tween to create a smooth transition effect
      	tween.stop()  # Stop any ongoing tweens
      	var selected_button = buttons[selected_index]
      	var previous_button = buttons[prev_index]
      
      	# Move using `rect_position` for UI elements
      	var selected_target_pos = selected_button.position + Vector2(0, -10)
      	var previous_target_pos = previous_button.position + Vector2(0, 10)
      
      	# Create the tweens (separately without chaining)
      	tween.tween_property(selected_button, "position", selected_target_pos, 0.1)
      	tween.set_trans(Tween.TRANS_SINE)
      	tween.set_ease(Tween.EASE_IN_OUT)
      
      	tween.tween_property(previous_button, "position", previous_target_pos, 0.1)
      	tween.set_trans(Tween.TRANS_SINE)
      	tween.set_ease(Tween.EASE_IN_OUT)
      
      func update_button_selection():
      	# Update button visuals based on selection
      	for i in range(buttons.size()):
      		var button = buttons[i]
      		var anim = button.get_node("MainAnimator")
      		anim.play("default")
      
      		# Check if this button is the currently selected one
      		if i == selected_index:
      			# Play the hover animation
      			var start = button.get_node("MainAnimator")
      			start.play("click")
      			var animation_player = button.get_node("ShadeBlink")  # Adjust the path if needed
      			animation_player.play("blink")  # Play the hover animation
      			$"../../CanvasLayer/Sprite2D".frame =4
      			
      func _on_button_pressed(button):
      	# Retrieve the index from the button's metadata
      	var index = button.get_meta("index")
      	
      	# Play the press animation
      	var animation_player = button.get_node("MainAnimator")  # Adjust the path if needed
      	animation_player.play("blinkLabel")  # Play the press animation
      
      	# Handle button press actions based on the index
      	match index:
      		0:
      			$"../../SFX/MenuAccept".play()
      			await $"../../SFX/MenuAccept".finished
      			Global.main.change_scene_to_file(save)
      		1:
      			$"../../SFX/MenuAccept".play()
      			await $"../../SFX/MenuAccept".finished
      			Global.main.change_scene_to_file(encore)
      		2:
      			$"../../SFX/MenuNotReady".play()
      		3:
      			$"../../SFX/MenuNotReady".play()
      		4:
      			$"../../SFX/MenuAccept".play()
      			await $"../../SFX/MenuAccept".finished
      			Global.main.change_scene_to_file(options)
      		5:
      			$"../../SFX/MenuAccept".play()
      			await $"../../SFX/MenuAccept".finished
      			Global.main.change_scene_to_file(Extras)			

      DaveTheCoder Okay so your saying that I set it up like this
      var tween = create_tween()
      tween.tween_property($Sprite, "position", Vector2.RIGHT * 300, 1).as_relative().set_trans(Tween.TRANS_SINE)
      tween.tween_property($Sprite, "position", Vector2.RIGHT * 300, 1).as_relative().from_current().set_trans(Tween.TRANS_EXPO)

      That's partly right. But you shouldn't call tween_property() twice for the same object and property.

        DaveTheCoder I got it to work but the animation doesn't look like the one in the video the buttons instead fall when selected

        
        extends Control
        
        @export var save = load("res://Data/Stages/Menu/SaveMenu.tscn")
        @export var encore = load("res://Data/Stages/Menu/EncoreMenu.tscn")
        @export var time = preload("res://Data/Stages/TZ/TestZonetime.tscn")
        @export var options = preload("res://Data/Stages/Menu/OptionsMenus.tscn")
        @export var Extras = preload("res://Data/Stages/Menu/ExtrasMenu.tscn")
        # Go back to title 
        @export var back = preload("res://Data/Stages/Title/Title.tscn")
        
        # Variables for button management
        var buttons: Array = []
        var selected_index: int = 0
        var tween
        
        # Called when the node enters the scene tree for the first time.
        func _ready():
        	buttons.clear()  # Clear any existing values (good practice)
        	
        	# Create a Tween instance
        	
        
        	# Loop through all child nodes of the Control node
        	for i in range(get_child_count()):
        		var button = get_child(i)
        		
        		# Check if the child is a TextureButton
        		if button is TextureButton:
        			buttons.append(button)  # Add it to the buttons array
        			button.set_meta("index", buttons.size() - 1)  # Store the button index as metadata
        			
        			# Connect the pressed signal using a lambda to pass the button
        			button.pressed.connect(Callable(self, "_on_button_pressed").bind(button))
        
        	# Set the initial selection
        	update_button_selection()
        
        func _input(event):
        	# Handle input for navigation
        	if event.is_action_pressed("gm_up"):
        		move_selection(-1)
        		$"../../CanvasLayer/Sprite2D".frame = 0
        		$"../../CanvasLayer/AnimationPlayer".play("tv")
        		$"../../SFX/MenuBleep".play()
        		
        	elif event.is_action_pressed("gm_down"):
        		move_selection(1)
        		$"../../CanvasLayer/Sprite2D".frame = 0
        		$"../../CanvasLayer/AnimationPlayer".play("tv")
        		$"../../SFX/MenuBleep".play()
        
        	# Handle 'gm_action' for triggering the selected button
        	elif event.is_action_pressed("gm_action"):
        		if selected_index >= 0 and selected_index < buttons.size():
        			buttons[selected_index].emit_signal("pressed")  # Manually emit the pressed signal for the selected button
        
        	elif event.is_action_pressed("gm_action2"):
        		Global.main.change_scene_to_file(back, "FadeOut")
        
        func move_selection(direction: int):
        	var prev_index = selected_index  # Store the previous index
        	selected_index += direction
        	
        	# Wrap around selection
        	if selected_index < 0:
        		selected_index = buttons.size() - 1  # Wrap to the last button
        	elif selected_index >= buttons.size():
        		selected_index = 0  # Wrap to the first button
        	
        	# Update button visuals and start tween animation
        	update_button_selection()
        	
        	# Stop any ongoing tweens to avoid conflicts
        
        
        	var selected_button = buttons[selected_index]
        	var previous_button = buttons[prev_index]
        	if selected_button != null and previous_button != null:
        		# Move using `rect_position` for UI elements
        		var selected_target_pos = selected_button.position + Vector2(0, -10)
        		var previous_target_pos = previous_button.position + Vector2(0, 10)
        		
        		# Tween to move the selected button slightly upward and the previous button downwa
        		tween = get_tree().create_tween()  # Create a new Tween instance
        	# Tween the selected button's position
        		tween.tween_property(selected_button, "position", selected_target_pos, 1).as_relative().set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
        		tween.tween_property(selected_button, "position", previous_target_pos, 1).as_relative().from_current().set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
        
        func update_button_selection():
        	# Update button visuals based on selection
        	for i in range(buttons.size()):
        		var button = buttons[i]
        		var anim = button.get_node("MainAnimator")
        		anim.play("default")
        
        		# Check if this button is the currently selected one
        		if i == selected_index:
        			# Play the hover animation
        			var start = button.get_node("MainAnimator")
        			start.play("click")
        			var animation_player = button.get_node("ShadeBlink")  # Adjust the path if needed
        			animation_player.play("blink")  # Play the hover animation
        			$"../../CanvasLayer/Sprite2D".frame = 4
        			
        func _on_button_pressed(button):
        	# Retrieve the index from the button's metadata
        	var index = button.get_meta("index")
        	
        	# Play the press animation
        	var animation_player = button.get_node("MainAnimator")  # Adjust the path if needed
        	animation_player.play("blinkLabel")  # Play the press animation
        
        	# Handle button press actions based on the index
        	match index:
        		0:
        			$"../../SFX/MenuAccept".play()
        			await $"../../SFX/MenuAccept".finished
        			Global.main.change_scene_to_file(save)
        		1:
        			$"../../SFX/MenuAccept".play()
        			await $"../../SFX/MenuAccept".finished
        			Global.main.change_scene_to_file(encore)
        		2:
        			$"../../SFX/MenuNotReady".play()
        		3:
        			$"../../SFX/MenuNotReady".play()
        		4:
        			$"../../SFX/MenuAccept".play()
        			await $"../../SFX/MenuAccept".finished
        			Global.main.change_scene_to_file(options)
        		5:
        			$"../../SFX/MenuAccept".play()
        			await $"../../SFX/MenuAccept".finished
        			Global.main.change_scene_to_file(Extras)

        I don't understand what you're trying to do with a tween. You haven't explained it clearly.

        I suggest that you create a new project for learning tweens. Keep it simple. Add a sprite, and experiment with using tweens on it until you fully understand how tweens work. Use the project only for testing tweens and nothing else. Keep the project as a reference.

          DaveTheCoder I am trying to make what is seen in the video where when up or down is pressed it scrolls the buttons up or down

          You want the button to move a short distance, and then move back? Then you need two tweens.

          Example:

          var tween: Tween
          
          tween = create_tween()
          # Move Sprite's position from (0,100) to (100,200) over 0.5 second.
          tween.tween_property($Sprite, "position", Vector2(100.0, 200.0), 0.5).from(Vector2(0.0, 100.0))
          
          # Wait for tween to finish.
          await tween.finished
          
          tween = create_tween()
          # Move Sprite's position from (100,200) to (0,100) over 0.5 second.
          tween.tween_property($Sprite, "position", Vector2(0.0, 100.0), 0.5).from(Vector2(100.0, 200.0))

          References:
          https://docs.godotengine.org/en/4.3/classes/class_tween.html
          https://docs.godotengine.org/en/4.3/classes/class_propertytweener.html
          https://docs.godotengine.org/en/4.3/tutorials/scripting/gdscript/gdscript_basics.html#awaiting-signals-or-coroutines

            No, that code used only one tween. It may have been intended for Godot 3.

            ChatGPT is useful for pointing you in the right direction, but you can't assume that its code is 100% correct. You have to go through it line by line and make corrections if needed.