Camera2D Mouse movement

Godot Version 4.3 Stable

I am trying to implement a function in my game (TopDown 2D) that allows the position of the Camera2D to be influenced by mouse movement. The camera is centered on the player, and you can use the mouse to look around. This works, but as soon as I enlarge the window of the running game, the position of the camera is no longer correct. The same thing happens when I set the Window Mode to Fullscreen in the Project Settings.

Camera2D script:

extends Camera2D

const MAX_OFFSET = 300.0
@export var player: CharacterBody2D

func _ready() -> void:
	if player:
		position = player.global_position

func _physics_process(delta):
	if player:
		update_camera_position()

func update_camera_position():
	var mouse_pos = get_viewport().get_mouse_position() - get_viewport().size / 2.0

	mouse_pos /= get_zoom().x
	mouse_pos.x = clamp(mouse_pos.x, -MAX_OFFSET, MAX_OFFSET)
	mouse_pos.y = clamp(mouse_pos.y, -MAX_OFFSET, MAX_OFFSET)

	position = player.global_position + mouse_pos

	position = position.round()
	
	print(mouse_pos)

Project Settings:

→ Display → Window
Size:
Viewport Width = 640
Viewport Height = 360
Mode = Windowed
Stretch:
Mode = viewport
Aspect = keep
Scale = 1.0
Scalemode = integer

→ Rendering -->2D
Snap 2D Transforms to Pixel = ON
Snap 2D Vertices to Pixel = ON

Thank you in advance.

To express my question more clearly:
Why does the value of this variable change:
var mouse_pos = get_viewport().get_mouse_position() - get_viewport().size / 2.0
after I have enlarged the window?
When I position the mouse in the center of the screen during the test run (after enlarging the window), the variable no longer gives the correct value.
The value of the X and Y axes should then output approximately 0, but after enlarging the window, it no longer does.

I think the problem is a mismatch between two coordinate systems, which are different, because the viewport gets stretched. If I understand the documentation correctly, Viewport.get_mouse_position() uses the viewport’s coordinate system, so the values are between (0, 0) and (640, 360) regardless of the window size. Using get_viewport().size on the other hand gives you the actual size of the window, which can be changed.

Maybe you could try using a constant value for the center of the screen.

var mouse_pos = get_viewport().get_mouse_position() - Vector2(320, 180)

Or perhaps there’s another more elegant solution, that I failed to notice.

1 Like

Thx for the help :grinning: :v:

But i solved the problem 10 minutes ago :sweat_smile:.
Here the full script:

extends Camera2D

@export var player: CharacterBody2D
var MAX_OFFSET_X: float
var MAX_OFFSET_Y: float


func _ready() -> void:
	if player:
		position = player.global_position
	position = position.round()
	set_max_offset()


func _physics_process(delta):
	if player:
		update_camera_position()
	position = position.round()


func set_max_offset():
	var window_size = get_viewport().size
	MAX_OFFSET_X = window_size.x * 0.5  
	MAX_OFFSET_Y = window_size.y * 0.5  


func update_camera_position():
	var mouse_pos = get_local_mouse_position()
	var player_pos = player.position
	
	mouse_pos.x = clamp(mouse_pos.x, -MAX_OFFSET_X, MAX_OFFSET_X)
	mouse_pos.y = clamp(mouse_pos.y, -MAX_OFFSET_Y, MAX_OFFSET_Y)
	
	set_position(mouse_pos + player_pos)
	print(mouse_pos)

The camera moves always correct on any window size.
I now try to add a Curve to make it smoother.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.