|
|
|
 |
Reply From: |
sysharm |
Unfortunately chanon’s script was made for 2d stretch mode which is not good for pixel perfect games. I adapted the scripts to use viewport stretch mode in Godot 3. Set the following script as an Autoload:
extends Node
# don't forget to use stretch mode 'viewport' and aspect 'ignore'
onready var viewport = get_viewport()
func _ready():
get_tree().connect("screen_resized", self, "_screen_resized")
func _screen_resized():
var window_size = OS.get_window_size()
# see how big the window is compared to the viewport size
# floor it so we only get round numbers (0, 1, 2, 3 ...)
var scale_x = floor(window_size.x / viewport.size.x)
var scale_y = floor(window_size.y / viewport.size.y)
# use the smaller scale with 1x minimum scale
var scale = max(1, min(scale_x, scale_y))
# find the coordinate we will use to center the viewport inside the window
var diff = window_size - (viewport.size * scale)
var diffhalf = (diff * 0.5).floor()
# attach the viewport to the rect we calculated
viewport.set_attach_to_screen_rect(Rect2(diffhalf, viewport.size * scale))
Thank you for this. This post and script was just what i was looking for!
Pixel perfect makes my camera abit jaggy when moving diagonally, but thats another story… Will have to make some clever camera script now.
fossegutten | 2018-05-02 17:43
i’m new so not sure this would work but in game maker i would usually draw things (including camera locations) at rounded coordinates.
usually rounded to the nearest integer, but perhaps in godot u need to round by ur upscale factor?
note i wouldn’t actually change the location of the objects, just the location they draw at
decroded | 2018-09-19 14:37
Trying this with Godot 3.1 beta 2 and the script will never be called. Only when setting the scale mode to 2D. But not when using “VIEWPORT”. Breaking change in 3.1?
René Ruppert | 2019-01-18 16:54
I just wanted to mention that this script helped me enormously while I was working on my pixel-based game, it allowed the game to run at the highest res possible without overlapping past the bounds of the screen, and did its job well. The only issue was that it was locked into a predefined aspect ratio, so when I switched over to using an ultrawide for development I was left with a ton of unused space. For some games where a specific aspect ratio/size is a design choice, this isn’t a problem, but for a more standard game like mine it is.
So, I modified the script a bit; it still works the same, but now after it finds its largest scale, it extends the sides of the viewport by pixel perfect amounts just as much as is needed to fill the entire screen. Hope this helps! (Please let me know if there is a simpler way to achieve the same result)
extends Node
# don't forget to use stretch mode 'viewport' and aspect 'ignore'
onready var viewport = get_viewport()
func _ready():
get_tree().connect("screen_resized", self, "_screen_resized")
func _screen_resized():
var window_size = OS.get_window_size()
# see how big the window is compared to the viewport size
# floor it so we only get round numbers (0, 1, 2, 3 ...)
var scale_x = floor(window_size.x / viewport.size.x)
var scale_y = floor(window_size.y / viewport.size.y)
# use the smaller scale with 1x minimum scale
var scale = max(1, min(scale_x, scale_y))
# extend the viewport to actually fit the screen as much as possible, in pixel perfect amounts
#find the scaled size difference (basically visual pixel difference) between the screen and viewport dimensions
var sizeDiff = window_size - (viewport.size * scale)
var pixelDiff = (sizeDiff/scale).ceil()
#If either dimension is odd, make it even by adding a pixel (otherwise you might have everything offset by a half pixel)
if int(pixelDiff.x) % 2 == 1:
pixelDiff.x += 1
if int(pixelDiff.y) % 2 == 1:
pixelDiff.y += 1
#Now actually scale up the viewport to make it fill the screen
viewport.set_size(viewport.size + pixelDiff)
# find the coordinate we will use to center the viewport inside the window
var diff = window_size - (viewport.size * scale)
var diffhalf = (diff * 0.5).floor()
# attach the viewport to the rect we calculated
viewport.set_attach_to_screen_rect(Rect2(diffhalf, viewport.size * scale))
SKison | 2020-01-25 07:00
Thanks SKIson that works really well for me!
nbeardsworth | 2020-09-03 18:49
This works perfect, nice : )
samsface | 2020-12-21 16:59