How we can create scene swipe horizontally in godot 4?

I have godot 4.2.1 project and in below I have four icons when I click the the icons I can open scenes, but when I click the icons or swipe scene screen, scenes will swipe horizontally like image below, my code is here:

extends Node2D

var scenes = {
 "one": "res://Scenes/One.tscn",
 "two": "res://Scenes/Two.tscn",
 "three": "res://Scenes/Three.tscn",
 "four": "res://Scenes/Four.tscn"
}
var current_screen_index = 0
var screen_container

var oneButton
var twoButton
var threeButton
var fourButton


func _ready():
    
 screen_container = Control.new()
 add_child(screen_container)

 oneButton = $HBoxContainer/TextureRect/HBoxContainerOne/OneButton
 twoButton = $HBoxContainer/TextureRect/HBoxContainerTwo/TwoButton
 threeButton = $HBoxContainer/TextureRect/HBoxContainerThree/ThreeButton
 fourButton = $HBoxContainer/TextureRect/HBoxContainerFour/FourButton

 oneButton.icon = preload("res://Assets/one.png")
 twoButton.icon = preload("res://Assets/two.png")
 threeButton.icon = preload("res://Assets/three.png")
 fourButton.icon = preload("res://Assets/four.png")

 oneButton.connect("pressed", Callable(self, "_on_one_button_pressed"))
 twoButton.connect("pressed", Callable(self, "_on_two_button_pressed"))
 threeButton.connect("pressed", Callable(self, "_on_three_button_pressed"))
 fourButton.connect("pressed", Callable(self, "_on_four_button_pressed"))


func _on_one_button_pressed():
 change_scene("one")

func _on_two_button_pressed():
 change_scene("two")

func _on_three_button_pressed():
 change_scene("three")

func _on_four_button_pressed():
 change_scene("four")

func change_scene(scene_name: String) -> void:
 if scenes.has(scene_name):
    var new_scene_resource = load(scenes[scene_name])
    if new_scene_resource is PackedScene:
        var new_scene = new_scene_resource.instantiate()
        if new_scene:
            # Add the new scene to the tree
            get_tree().root.add_child(new_scene)

            if get_tree().current_scene:
              get_tree().current_scene.queue_free()
            get_tree().current_scene = new_scene
        else:
            print("Error: failed to instance the scene.")
    else:
        print("Error: scene not found.")

func _input(event):
   if event is InputEventMouseMotion:
       var hovered_buttons = []
       if oneButton.is_hovered():
           hovered_buttons.append(oneButton)
       if twoButton.is_hovered():
           hovered_buttons.append(twoButton)
       if threeButton.is_hovered():
           hovered_buttons.append(threeButton)
       if fourButton.is_hovered():
           hovered_buttons.append(fourButton)

1706873985-758804-3veru

and scene tree like that:
Screenshot 2024-02-07 224158

Dunno. This video seems pretty good: https://www.youtube.com/watch?v=Hz9-j3ceDag

They use an AnimationPlayer node and connect animation_finished signal to a func which does the scene switch.

tnx so much but it is not related about my question as I saw

Sorry. I read “wipe” instead of “swipe”. My bad!

I did not find any solution since 1 month :frowning:

It looks like you are not trying to detect a “swipe” in any way. I am not sure if there is an event on mobile that you can detect, but you could look for general mouse events. I am thinking left-click and drag over some minimum span of horizontal space. If there is such a “drag” then you could call it a “swipe”.

So, set a flag when left-button is down and mouse is moving and the movement (x) lasted > n pixels, then emit your own “swipe” event and move to the next gui thing.

I update my code but it is just work by clicking to scene, it is not able to change scenes by swipe with finger, even godot 4.2.1 support the mobile apps, I did not find sample like that in community, here my last updated code:

extends Node2D

var scenes = {
 "one": "res://Scenes/One.tscn",
 "two": "res://Scenes/Two.tscn",
 "three": "res://Scenes/Three.tscn",
 "four": "res://Scenes/Four.tscn"
}
var current_screen_index = 0
var screen_container

var oneButton
var twoButton
var threeButton
var fourButton

var swipe_start = Vector2.ZERO
var swipe_end = Vector2.ZERO

func _ready():
    
 screen_container = Control.new()
 add_child(screen_container)

 oneButton = $HBoxContainer/TextureRect/HBoxContainerOne/OneButton
 twoButton = $HBoxContainer/TextureRect/HBoxContainerTwo/TwoButton
 threeButton = $HBoxContainer/TextureRect/HBoxContainerThree/ThreeButton
 fourButton = $HBoxContainer/TextureRect/HBoxContainerFour/FourButton

 oneButton.icon = preload("res://Assets/one.png")
 twoButton.icon = preload("res://Assets/two.png")
 threeButton.icon = preload("res://Assets/three.png")
 fourButton.icon = preload("res://Assets/four.png")

 oneButton.connect("pressed", Callable(self, "_on_one_button_pressed"))
 twoButton.connect("pressed", Callable(self, "_on_two_button_pressed"))
 threeButton.connect("pressed", Callable(self, "_on_three_button_pressed"))
 fourButton.connect("pressed", Callable(self, "_on_four_button_pressed"))

func _on_one_button_pressed():
 change_scene("one")

func _on_two_button_pressed():
 change_scene("two")

func _on_three_button_pressed():
 change_scene("three")

func _on_four_button_pressed():
 change_scene("four")

func change_scene(scene_name: String) -> void:
 if scenes.has(scene_name):
    var new_scene_resource = load(scenes[scene_name])
    if new_scene_resource is PackedScene:
        var new_scene = new_scene_resource.instantiate()
        if new_scene:
            # Add the new scene to the tree
            get_tree().root.add_child(new_scene)

            if get_tree().current_scene:
              get_tree().current_scene.queue_free()
            get_tree().current_scene = new_scene
        else:
            print("Error: failed to instance the scene.")
    else:
        print("Error: scene not found.")

func _input(event):
   if event is InputEventMouseMotion:
       var hovered_buttons = []
       if oneButton.is_hovered():
           hovered_buttons.append(oneButton)
       if twoButton.is_hovered():
           hovered_buttons.append(twoButton)
       if threeButton.is_hovered():
           hovered_buttons.append(threeButton)
       if fourButton.is_hovered():
           hovered_buttons.append(fourButton)

   if event is InputEventMouseButton:
       if event.pressed:
           swipe_start = event.position
       else:
           swipe_end = event.position
           handle_swipe()


func handle_swipe():
   var swipe_direction = swipe_end - swipe_start
   if abs(swipe_direction.x) > abs(swipe_direction.y):
       if swipe_direction.x < 0:
           # Swipe left
           current_screen_index = (current_screen_index + 1) % 4
       else:
           # Swipe right
           current_screen_index = (current_screen_index - 1) % 4
   change_scene(["one", "two", "three", "four"][current_screen_index])

Okay. I’ll assume the current_screen_index is a valid number and the various vars in your hand_swipe func are all sensible. You are still simply calling change_scene which does a hard scene replace.

To scroll in the guis on the left and right, you need to animate them. Or animate the entire container somehow. Keep in mind, I’ve not done this so I am guessing a bit.

Depending on how heavy the contents of each linear-layout is, you could load or preload the scene into a variable. Have a placeholder and when the layout is scrolled-into the screen, do a node-replace (on the inside of it) with the scene.

Use load() instead of preload() if the path isn’t known at compile-time.
var scene = preload(“res://scene.tscn”).instantiate()
Add the node as a child of the node the script is attached to.
add_child(scene)

I will try tnx :slight_smile:, but I dont know how I will animate whole scenes

Then move HBoxContainerOne left and right to show the correct one.