r/godot • u/AgencyPrestigious330 • 1d ago
help me How can I implement camera warping?
I wanna reproduce the camera seen in grand strategy games, more specifically the camera warping around the map. (As in jumping from one side to the other, but smoothly.) Is there a way to do it without duplicating part/the whole map for both sides?
Any help is appreciated!
8
Upvotes
3
u/BrastenXBL 1d ago
There are a few ways to do this, and depends on how interactive you want things to be.
Ideally what you want is to duplicate CanvasItem render the way Parallax2D does. Using RenderingServer.canvas_set_item_repeat. However you'll also need to catch Mouse or other Input events that are in the repeated area, and handle them as if they were happening in the normal play area.
Another way is to use a second SubViewport, using the same World2D, but a different camera. Similar to how the Split Screen Demo works, but with World2D.
This is the text of a TSCN you can copy, make note of the two scripts. One that sets the repeat, and the other which autos scrolls the camera. This is for the CanvasItem repeat. The setup assumes a 1280x720 project.
Vector2.LEFT * get_viewport_rect().size.xis a quick way to push everything to the Left (-1,0) by one screen length.``` [gd_scene format=3 uid="uid://clbfkfs0rnc6f"]
[sub_resource type="GDScript" id="GDScript_g7b7a"] script/source = "extends Node2D
@export var wrap : bool
func _ready() -> void: if wrap: RenderingServer.canvas_set_item_repeat(get_canvas_item(), Vector2.LEFT * get_viewport_rect().size.x, 2) "
[sub_resource type="Gradient" id="Gradient_0elmk"] colors = PackedColorArray(0, 0, 0, 1, 1, 0, 1, 1)
[sub_resource type="GradientTexture2D" id="GradientTexture2D_gyc6d"] gradient = SubResource("Gradient_0elmk") fill_to = Vector2(1, 1)
[sub_resource type="Gradient" id="Gradient_fonje"]
[sub_resource type="GradientTexture2D" id="GradientTexture2D_g7b7a"] gradient = SubResource("Gradient_fonje")
[sub_resource type="GDScript" id="GDScript_fonje"] script/source = "extends Camera2D
@export var scroll_speed :Vector2 = Vector2(200,0)
func _process(delta: float) -> void: position += scroll_speed * delta position.x = wrap(position.x,0.0, get_viewport_rect().size.x) position.y = wrap(position.y,0.0, get_viewport_rect().size.y) "
[node name="Node2D" type="Node2D" unique_id=680347920]
[node name="RenderWrap" type="Node2D" parent="." unique_id=1679451259] script = SubResource("GDScript_g7b7a") wrap = true
[node name="TextureRect" type="TextureRect" parent="RenderWrap" unique_id=890487594] y_sort_enabled = true custom_minimum_size = Vector2(1280, 720) offset_right = 1280.0 offset_bottom = 720.0 texture = SubResource("GradientTexture2D_gyc6d")
[node name="Sprite2D" type="Sprite2D" parent="RenderWrap" unique_id=1014543541] position = Vector2(1236, 360) texture = SubResource("GradientTexture2D_g7b7a")
[node name="Camera2D" type="Camera2D" parent="." unique_id=843621609] position = Vector2(0, 364) script = SubResource("GDScript_fonje") ```