Godot Version
4.4.1 stable
Question
Hi! I’m new to the forums and new to Godot.
I’m trying to get my camera settings to change when the device rotates but I can’t seem to get the behaviour I am looking for.
I’d like to keep the top and bottom bounds at the edges of the game screen regardless of the device orientation, or at least keep the viewport centred vertically so it can expand horizontally.
See in the image, we’re simply seeing either more or less of the game world, depending on the orientation of the device. The device acts more like a window into the world.
I have aspect set to expand, but what I’ve found by playing with the project settings is that the viewport seems to be ‘pinned’ to the top-left of the screen, so when I rotate the device from landscape to horizontal the game world is stuck in the top of the screen, like this:
Does anyone have anything new to try? I’ve been adjusting settings and looking at other tutorials but I can’t find the effect I"m looking for!
I think when the screen rotates you would have to change the zoom of the camera as from your image the zoom you want on rotate is different.
I presume you are using screen_get_orientation from the display server.
I don’t think there is a signal for if this changes, so I guess you would have to poll it in a process somewhere. When you detect a change you can adjust the zoom to your preferred for that orientation.
Something like this:
func _process(delta):
var current_orientation = DisplayServer.screen_get_orientation()
if current_orientation != last_orientation:
last_orientation = current_orientation
adjust_camera_zoom()
Where adjust_camera_zoom would set to your predefined constants for each view to match your scene size.
Screen orientation return values in the docs:
I have never done this by the way, but I thought it was an interesting question so I wanted to check the docs.
Hope that helps.
Hey, this is really helpful, thanks!
I’m so new to Godot I didn’t fully appreciate the difference between a viewport and a camera - I’d been playing around with viewport settings but ignoring Camera2D.
Using this to detect orientation changes has gotten me a lot of the way there, I just need to figure out how to calculate the correct zoom settings now!
1 Like
Mini update for anyone looking to detect device rotation: my code to detect orientations ended up looking like this
func _process(_delta):
var size = get_viewport().size
var current_orientation = ""
if size.x > size.y:
current_orientation = "landscape"
else:
current_orientation = "portrait"
if current_orientation != last_orientation:
last_orientation = current_orientation
on_orientation_changed(current_orientation)
DisplayServer.screen_get_orientation()
was only reporting SCREEN_SENSOR
regardless of the orientation.
This is the code that seems to make the effect I want, in case you were interested in the solution
extends Camera2D
var last_orientation = ""
var screen_size: Vector2
var reference_size: Vector2 #this is the viewport size in scene
func _ready() :
screen_size = get_viewport().size
reference_size.x = 1080
reference_size.y = 1920
print(str(screen_size))
#assets in the game will be made at PORTRAIT size, so we need to scale down
if screen_size.x > screen_size.y: #if in landscape, normalize the screen size for portrait
var old_y = screen_size.y
screen_size.y = screen_size.x
screen_size.x = old_y
print("portrait size: "+ str(screen_size))
func _process(_delta):
var size = get_viewport().size
var current_orientation = ""
if size.x > size.y:
current_orientation = "landscape"
else:
current_orientation = "portrait"
if current_orientation != last_orientation:
last_orientation = current_orientation
on_orientation_changed(current_orientation)
func on_orientation_changed(orientation):
if orientation == "portrait":
print("Switched to portrait")
adjust_camera_for_portrait()
elif orientation == "landscape":
print("Switched to landscape")
adjust_camera_for_landscape()
func adjust_camera_for_portrait():
zoom = Vector2(1.0, 1.0)
func adjust_camera_for_landscape():
var scale = reference_size.y / screen_size.y
zoom = Vector2(scale, scale)
1 Like
I think this can also be accomplished in project settings, by changing stretch mode to canvas items, and stretch aspect to keep height. The base viewport size would be the size of the portrait mode, or at least something with the same ratio as it.
1 Like
I just tried this out - it behaves like you expected!
The only drawback is that it doesn’t adapt to screen sizes that are taller than the viewport - it adds black bars in portrait mode.
It’s much closer than anything else I found just using the project settings, so thank you
I think my viewport was landscape shaped when I was experimenting with this approach before. For now the script further above is doing a great job.
1 Like